Integer i=3 vs Integer i= new Integer (3) [duplica

2020-02-05 04:09发布

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?

标签: java
9条回答
男人必须洒脱
2楼-- · 2020-02-05 04:48

In Following Piece of Code:

Integer i=3;
Integer j=3;
if(i==j)
   System.out.println("i==j");

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:

Integer i=3;
Integer j=new Integer(3);
if(i==j)
   System.out.println("i==j");

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.

查看更多
\"骚年 ilove
3楼-- · 2020-02-05 04:50

Java pools integers between -128 and 127 and hence both the references are the same.

Integer i=3;
Integer j=3;

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:

Integer j=new Integer(3);

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

Integer i=3;
Integer j=new Integer(3);
if(i==j)
   System.out.println("i==j"); // **does not print**
查看更多
冷血范
4楼-- · 2020-02-05 04:56

It's to do with how boxing works. From the JLS section 5.1.7:

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

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, as new 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:

Integer x = 127;
Integer y = 127;
System.out.println(x == y); // Guarantee to print true

Whereas this could go either way:

Integer x = 128;
Integer y = 128;
System.out.println(x == y); // Might print true, might print false
查看更多
我命由我不由天
5楼-- · 2020-02-05 04:57

No they shouldn't, because java can use pre-fabricated Integer objects for small numbers when autoboxing.

查看更多
倾城 Initia
6楼-- · 2020-02-05 04:59
Integer i=3;
Integer j=3;
if(i==j)System.out.println("i==j");

Here, 3 is being auto-boxed and hence i and j point to the same Integer.

Integer i=3;
Integer j=new Integer(3);
if(i==j)System.out.println("i==j"); // does not print

Here, i points to the auto-boxed Integer whereas j points to a new Integer and hence there references fail the equals == operator test.

But, here's some more food for thought.

Integer i=300;
Integer j=300;
if(i!=j)System.out.println("i!=j"); // prints i!=j

Why? Because, auto-boxing shares Integer instances between -128 to 127 only. This behaviour, however, may differ between different Java implementations.

查看更多
▲ chillily
7楼-- · 2020-02-05 05:01

Interpreter/JIT optimizer can put all 3's in same box. But if you force a "new" then you get another address.

Try

 j=8; // after initialization of i and j

then see the j's address changed for first version.

查看更多
登录 后发表回答