I came across a code snippet on StackOverflow:
Integer a = 42;
Integer b = 42;
Integer c = 555;
Integer d = 555;
System.out.println(a == b); // prints true
System.out.println(c == d); // prints false
Wait, what?
The second comparison evaluating to false makes sense. In Java, when ==
is
used with reference operands, equality means they point to the same object in
memory (primitives are compared literally). So c == d
should return false,
because they’re separate objects in memory (even if representing the same number
underneath). But why does the first comparison equate to true?
The answer can be found in the Java Langauge Specification, chapter 5 . Two primitives being autoboxed into references via a boxing conversion may qualify to be cached for optimization purposes. Caching the more commonly used primitive values leads to faster access time, so these certain commonly used primitives are cached:
true
,false
byte
orchar
in the range\u0000
to\u007f
int
orshort
in the inclusive range of -128 to 127
So in the snippet above, a == b
is true because a
and b
are between -128
and 127, so when a new Integer a = 42;
is created, it simply points to a
previously cached Integer object.
Note that this only works when primitive int
s are autoboxed to Integer
s. If
two Integer
objects are created (not autoboxed from the primitive type)…
Integer e = new Integer(4);
Integer f = new Integer(4);
System.out.println(e == f);
…then the comparison will be false, since both Integer
references were
explicitly initialized as separate objects.
Interesting stuff!