Consider this code:
class test {
public static void main(String[] args) {
test inst_test = new test();
int i1 = 2000;
int i2 = 2000;
int i3 = 2;
int i4 = 2;
Integer Ithree = new Integer(2); // 1
Integer Ifour = new Integer(2); // 2
System.out.println( Ithree == Ifour );
inst_test.method( i3 , i4 );
inst_test.method( i1 , i2 );
}
public void method( Integer i , Integer eye ) {
System.out.println(i == eye );
}
}
It prints:
false
true
false
I understand the first false
, the == operator only checks if two references are working on the same object, which in this case aren't.
The following true
and false
have me scratching my head. Why would Java consider i3
and i4
equal but i1
and i2
different? Both have been wrapped to Integer, shouldn't both evaluate to false? Is there a practical reason for this inconsistency?
Autoboxing of primitives into objects (as used in your calls to method
uses a cache of small values. From the Java Language Specification section 5.1.7:
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
The discussion part of the spec immediately following that is interesting too. Notably a JVM can cache more values if it wants to - you can't be sure of the results of doing:
Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);