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 == Ydoes not compile is to be expected, being different objects. - I'm a little surprised that
Y == 9istrue, given that 9 is by default anint, and given that 1) didn't even compile. Note that you can't put anintinto 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
xis autoboxed to andInteger. - Not surprising, as objects in different classes should not be
equal(). - What??
X == yistruebutX.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.
Xunboxed, then same value, so equal.- Same value, so equal.
ycannot be boxed to anIntegerso cannot be equal.