When you're comparing object references, ==
is defined as being true
when the references refer to the same object, not equivalent objects. (That's what equals
is for.)
With primitives, ==
is defined as being true
for equivalent values.
In your first example, you have two different objects, one assigned to a
and another assigned to b
. This is because the primitive you're trying to assign to the reference type is "autoboxed" (automatically wrapped in the equivalent object type for the primitive). Your code:
Object a = 128;
Object b = 128;
...is effectively treated like this:
Object a = Integer.valueOf(128);
Object b = Integer.valueOf(128);
...where Integer.valueOf
returns an Integer
object wrapping the value you give it, which may or may not be the same object for subsequent calls with the same value, depending on what value you give it. From the Javadoc:
If a new Integer
instance is not required, this method should generally be used in preference to the constructor Integer(int)
, as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
So this means that when you ran it with the value 127, you got the same object back for each call to Integer.valueOf
, and so ==
worked. But for 128, you got different objects back for each call, and so ==
didn't work, because again it checks that two references refer to the same object, not equivalent ones.