I'm a bit confused about the way Java treats ==
and equals()
when it comes to int
, Integer
and other types of numbers. For example:
Integer X = 9000;
int x = 9000;
Short Y = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
// results.add(X == Y); DOES NOT COMPILE 1)
results.add(Y == 9000); // 2)
results.add(X == y); // 3)
results.add(X.equals(x)); // 4)
results.add(X.equals(Y)); // 5)
results.add(X.equals(y)); // 6)
System.out.println(results);
outputs (maybe you should make your guess first):
[true, true, true, false, false]
- That
X == Y
does not compile is to be expected, being different objects. - I'm a little surprised that
Y == 9
istrue
, given that 9 is by default anint
, and given that 1) didn't even compile. Note that you can't put anint
into a method expecting aShort
, yet here they are equal. - This is surprising for the same reason as two, but it seems worse.
- Not surprising, as
x
is autoboxed to andInteger
. - Not surprising, as objects in different classes should not be
equal()
. - What??
X == y
istrue
butX.equals(y)
isfalse
? Shouldn't==
always be stricter thanequals()
?
I'd appreciate it if anyone can help me make sense of this. For what reason do == and equals() behave this way?
Edit: I have changed 9 to 9000 to show that this behavior is not related to the any unusual ways that the integers from -128 to 127 behave.
2nd Edit: OK, if you think you understand this stuff, you should consider the following, just to make sure:
Integer X = 9000;
Integer Z = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
results.add(X == Z); // 1)
results.add(X == y); // 2)
results.add(X.equals(Z)); // 3)
results.add(X.equals(y)); // 4)
System.out.println(results);
outputs:
[false, true, true, false]
The reason, as best as I understand it:
- Different instance, so different.
X
unboxed, then same value, so equal.- Same value, so equal.
y
cannot be boxed to anInteger
so cannot be equal.