In Java 1.4 and before, the equality operators == and != allow you to compare two booleans, two numbers, or two references. Any other combination of operands was a compilation error.
In Java 1.5 auto-unboxing enters the picture. It is now possible to compare a boolean with a Boolean, and a number of primitive type with a number expressed as a reference type. That is, it is no longer a compilation error to use the equality operators with a primitive on one side and a reference type on the other. (The public review draft for autoboxing doesn't get this right. I have reported the bug, and the beta-release implementation appears to be correct.)
Now where it really starts to get interesting
public class Equality {
public static void main(String[] args) {
Integer i = new Integer(0), j = new Integer(0);
// The two objects are both equal to 0
System.out.println(i == 0 && j == 0);
// But they are not equal to each other
System.out.println(i == j);
// true: relational ops unbox both sides
System.out.println(i <= j && i >= j);
}
Another wrinkle is that we'd get different results if we'd used autoboxing to create the two wrapper objects we wanted to compare. Unlike the code above, this code prints true:
Integer i = 0, j = 0; System.out.println(i == j);
The reason is that the autoboxing spec requires that small integers (-128 to 127) always box to the same wrapper object. Implementations are encouraged, but not requied, to do the same for larger values as well. So if we used 1023 instead of 0 in the code above it might print "true" or it might print "false".
None of this is intended as a criticism of autoboxing, by the way. Just an exploration of an interesting (and necessary) limitation.




Using jdk1.5 beta 1, I get:
Integer i = 0, j = 0;
System.out.println(i == j);
.. to print false.
Integer.valueOf( int value) does only return a new Integer( value), and Integer( int value) only stores the value.
Perhaps thats good, even though using a flyweight or similar, probably would increase performace.
Personally I think transalting:
Integer i = 0; to
Integer i = Integer.valueOf(0);
is sad, since it removes backwards compability. Iteger.valueOf( int) is added in Java1.5.
> Using jdk1.5 beta 1, I get:
>
> Integer i = 0, j = 0;
> System.out.println(i == j);
>
> .. to print false.
Hmm. Maybe I should have tested it... This is a bug. The autoboxing spec says that integers between -128 and 127 must always box to identical objects.
I believe that this will be fixed in the next beta release.
'Implementations are encouraged, but not requied, to do the same for larger values as well. So if we used 1023 instead of 0 in the code above it might print "true" or it might print "false". '
this feature enhances the saying "write once - test everywhere" :-)
i wonder what this would print in the fixed up beta:
Integer i,j;
int n;
//...
i = j = n;
System.out.println(i == j);