Comparing wrapper class with primitive using equals() gives strange behavior
Asked Answered
F

8

21

Consider below code snap. we use equals() to compare objects are meaningfully equivalent or not ? Here both value are meaningfully equal but why does longWrapper.equals(0) return false ? And when I compared both value with == operator it returns true.

    Long longWrapper = 0L;
    long longPrimitive = 0;

    System.out.println(longWrapper == 0L); // true
    System.out.println(longWrapper == 0); //true
    System.out.println(longWrapper == longPrimitive); //true


    System.out.println(longWrapper.equals(0L)); //true
    System.out.println(longWrapper.equals(0));  //false
    System.out.println(longWrapper.equals(longPrimitive)); //true
Fearnought answered 20/2, 2015 at 7:46 Comment(0)
C
21

longWrapper.equals(0) returns false, because 0 is autoboxed to Integer, not to Long. Since the two types are different, .equals() returns false.

In the meantime, longWrapper == 0 is true, because the longwrapper value is unboxed to 0, and 0 == 0 without considering the actual primitive types.

Carbuncle answered 20/2, 2015 at 7:51 Comment(0)
A
5

Its because 0 is not a long - its an int, and wrappers don't convert Integer's to Long's

Anagoge answered 20/2, 2015 at 7:50 Comment(0)
C
2

When you compare 0 == 0L, you're comparing an int literal to a long literal. The int gets promoted to a long, and then their values are compared. Since both are zeroes, the result is true.

When you add autoboxing to the mix, things are slightly different. A primitive is always autoboxed to its wrapper type. Here, 0, which is an int literal, is autoboxed to a java.lang.Integer wrapper instance. Since java.lang.Long and java.lang.Integer are different classes, equals between them must return false.

Canorous answered 20/2, 2015 at 7:51 Comment(0)
B
2

System.out.println(0L == 0) is True.

so longWrapper == 0 which unboxed and result is True.

And in Long.equals written as -

781     public boolean More ...equals(Object obj) {
782         if (obj instanceof Long) {
783             return value == ((Long)obj).longValue();
784         }
785         return false;
786     }

so System.out.println(longWrapper.equals(0)); return false as 0 will be boxed in Integer and if (obj instanceof Long) is false.

Breslau answered 20/2, 2015 at 8:0 Comment(0)
A
1

This one:

System.out.println(longWrapper == 0);

is comparing with ==, so it unboxes your Long, and you are comparing two primitives, both of which are zero.

This one:

System.out.println(longWrapper.equals(0));

is comparing with equals, so it boxes up the (int) zero as an Integer. A Long object is never equal to an Integer object, even if they are holding the same number.

Armstrong answered 20/2, 2015 at 7:53 Comment(0)
S
0

I think it is because the 0 in the equals method is an Integer. When you define the longPrimitive with 0 this 0 is casted to a long-value. the equals method accepts all objects and because of this the 0 stays an integer and is not casted. My guess is that in the equals method there is a call if the given object is an instance of long and since this 0 is an Integer it results in false. I hope this helps you

Slovene answered 20/2, 2015 at 7:51 Comment(0)
C
0

The equals method of Long explains why

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/lang/Long.java#Long.equals%28java.lang.Object%29

There is line there

 if (obj instanceof Long) {

longWrapper.equals(0) the paramter would become of type Integer.

On the other hand longWrapper.equals(longPrimitive) will box the pameter into Long

Chorale answered 20/2, 2015 at 7:58 Comment(0)
S
0

From Long.java class:

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}

So when you compare a Long to an int using equals, the if condition fails and the method returns false.

The other methods return true due to autoboxing and unboxing

Sassan answered 20/2, 2015 at 7:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.