19
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?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
OOP
  • 199
  • 1
  • 4

7 Answers7

39

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

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
13

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.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 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";` – Rob Jan 25 '19 at 10:27
  • @Rob true that. Also, this answer is very old, not sure I'd write the same today – Sean Patrick Floyd Jan 28 '19 at 18:49
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!

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.

Community
  • 1
  • 1
Zoltan Balazs
  • 837
  • 5
  • 7
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

Gaim
  • 6,734
  • 4
  • 38
  • 58
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.

Endre Moen
  • 695
  • 2
  • 9
  • 19
0

The answer you want is here

Pere Villega
  • 16,429
  • 5
  • 63
  • 100