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

7

20
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.println(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?

Amide answered 28/7, 2010 at 10:9 Comment(0)
P
40

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).

Pharmacopoeia answered 28/7, 2010 at 10:14 Comment(5)
thank Felix Kling very much . I understood this codeAmide
That doesn't explain why a1==a2.Streetman
The question was about b1==b2 and c1==c2, if I'm not mistaken.Phthisis
a1==a2 because they are primitive "int" types, not the Integer object typeBush
The range is between - 128 and 127.Disorganization
D
14

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.

Dowser answered 28/7, 2010 at 10:53 Comment(2)
>This is awful code. Objects should be initialized as Objects through constructors or factory methods. That's not entirely true. When you're creating instance of the String the best practice is to write String str = "str";Requirement
@Requirement true that. Also, this answer is very old, not sure I'd write the same todayDowser
T
2

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.

Top answered 28/7, 2010 at 10:13 Comment(0)
E
2

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

Ephebe answered 28/7, 2010 at 10:14 Comment(0)
H
2
  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!

Handtohand answered 13/7, 2012 at 12:3 Comment(1)
+1 for this quote from sources. Also the first answer with correct range!Disorganization
D
0

The answer you want is here

Diplosis answered 28/7, 2010 at 10:11 Comment(0)
B
0

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.

Barbie answered 22/8, 2013 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.