I am comparing 2 pieces of code. First
Integer i=3;
Integer j=3;
if(i==j)
System.out.println("i==j"); //prints i==j
Second,
Integer i=3;
Integer j=new Integer(3);
if(i==j)
System.out.println("i==j"); // does not print
I have doubt that in the first snippet why i==j
is being printed? Shouldn't the references be different?
In Following Piece of Code:
Here, "==" compares reference with each other rather than the value. So, Integer i and j both are referring to same reference in the memory.
while in Following Piece of Code:
The reference to both values are changed because 'j' is newly created object/reference of Integer in memory while 'i' is just referring to a value.
Therefore, the output of 1st code is "i==j" and 2nd code does not have any output.
Hope this helps.
Java pools integers between -128 and 127 and hence both the references are the same.
This results in autoboxing and 3 is converted to Integer 3. So for i is referring to an Integer object that is in constant pool, now when you do j=3, the same reference as that of i is assigned to j.
Whereas below code:
always results in a new Integer creation, in heap. This is not pooled. And hence you see that both reference are referring to different objects. Which results in
It's to do with how boxing works. From the JLS section 5.1.7:
Basically, a Java implementation must cache the boxed representations for suitably small values, and may cache more. The
==
operator is just comparing references, so it's specifically detecting whether the two variables refer to the same object. In the second code snippet they definitely won't, asnew Integer(3)
definitely isn't the same reference as any previously created one... it always creates a new object.Due to the rules above, this code must always give the same result:
Whereas this could go either way:
No they shouldn't, because java can use pre-fabricated Integer objects for small numbers when autoboxing.
Here,
3
is being auto-boxed and hencei
andj
point to the sameInteger
.Here,
i
points to the auto-boxedInteger
whereasj
points to a newInteger
and hence there references fail the equals==
operator test.But, here's some more food for thought.
Why? Because, auto-boxing shares
Integer
instances between -128 to 127 only. This behaviour, however, may differ between different Java implementations.Interpreter/JIT optimizer can put all 3's in same box. But if you force a "new" then you get another address.
Try
then see the j's address changed for first version.