开发者

Java question about autoboxing and object equality / identity [duplicate]

This question already has answers here: Weird Integer boxing in Java (12 answers) Closed 6 years ago.
public class Main { 
    /** 
      * @param args the command line arguments */ 
    public static void main(String[] args) { 
        // TODO code application logic here
        int a1 = 1000, a2 = 1000; 
        System.out.print开发者_StackOverflowln(a1==a2);//=>true 
        Integer b1 = 1000, b2 = 1000;
        System.out.println(b1 == b2);//=>false 
        Integer c1 = 100, c2 = 100; 
        System.out.println(c1 == c2);//=>true 
    }

}

Why is b1 == b2 false and c1 == c2 true?


Read this.

Java uses a pool for Integers in the range from -128 to 127.

That means if you create an Integer with Integer i = 42; and its value is between -128 and 128, no new object is created but the corresponding one from the pool is returned. That is why c1 is indeed identical to c2.

(I assume you know that == compares references, not values, when applied to objects).


The correct answers have already been given. But just to add my two cents:

Integer b1 = 1000, b2 = 1000;

This is awful code. Objects should be initialized as Objects through constructors or factory methods. E.g.

 // let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);

or

 // always use a new object
 Integer b2 = new Integer(1000);

This code

Integer b1 = 1000, b2 = 1000;

on the other hand implies that Integer was a primitive, which it is not. Actually what you are seeing is a shortcut for

Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);

and Integer only pools objects from -127 to 127, so it will create two new Objects in this case. So although 1000 = 1000, b1 != b2. This is the main reason why I hate auto-boxing.


Because Integer is for a few low numbers like enumeration so there is always same instance. But higher numbers creates new instances of Integer and operator == compares their references


You can find the answer here:

Strangest language feature in the 6th answer.

Edit: sorry not exatly the answer. The point is that == compares references, not values when you use it with Integer. But with int "==" means equals.


  public static Integer valueOf(int i) {
      final int offset = 128;
      if (i >= -128 && i <= 127) { // must cache
          return IntegerCache.cache[i + offset];
      }
       return new Integer(i);
    }

Because of this you true in one case, and false in other!


The answer you want is here


If autounboxing had worked also when doing equality checking with the '==' operator you could write:

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( notNullSafeLong1 == notNullSafeLong2) {
      do suff

This would require implementing an override for == so that null==someLong is false and the special case Null==Null is true. Instead we have to use equal() and test for null

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) || 
      (notNullSafeLong1 != null && notNullSafeLong2 != null & 
        notNullSafeLong1.equals(notNullSafeLong2)) {
      do suff    

This is alittle more verbose than the first example - if autounboxing had worked for the '==' operator.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜