Using == operator in Java to compare wrapper objects

21,420

Solution 1

The key to the answer is called object interning. Java interns small numbers (less than 128), so all instances of Integer(n) with n in the interned range are the same. Numbers greater than or equal to 128 are not interned, hence Integer(1000) objects are not equal to each other.

Solution 2

If you look at the source code for Integer you'll see that Integer.valueOf(int) pools all values -128 to 127. The reason is that small Integer values are used frequently and are thus worthy of being pooled/cached.

Taken straight from Integer.java:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

Note that this pooling is implementation specific and there's no guarantee of the pooled range.

The answers about interning are correct in concept, but incorrect with terminology. Interning in Java normally implies that the Java runtime is performing the pooling (such as String's intern). In Integer's case it's the class itself that is doing the pooling. There's no JVM magic involved.

Solution 3

The above answer about Interning is right on. Something to consider though if you do:

Integer i3 = new Integer(10);
Integer i4 = new Integer(10);

You will not have the new objects since you have created new objects explictly. If you write the code as follows it will be interned:

Integer i3 = Integer.valueOf(10);
Integer i4 = Integer.valueOf(10);

They will now be the same object again. If you take a look at the valueOf Method inside of the Integer.java class in the src.zip file you can see where it checks to see if the value of the int is outside of -128 to 127 it calls the new Integer class otherwise it loads it from the cache.

Solution 4

Integer i1 = 1000;
Integer i2 = 1000;

The compiler 'boxes' the int 1000 as Integer object. To do this it converts the source to the following:

Integer i1 = Integer.valueOf(1000);
Integer i2 = Integer.valueOf(1000);

Now valueOf could be a simple call to new Integer(1000) however creating a new Integer object every time an int is boxed would cost both time and space. To avoid this the Integer class keeps an array of Integer objects for a limited range of int values.

if(value> maxRange || value< minRange){
     //not in pool return new Integer
     return new Integer(value);
}else{
     //return pooled Integer object
     //for the value, pool contains all Integer
     //values from minRange to maxRange
     return integerPool[value-minRange];
}

The speed gained vs. the memory lost to this can be adjusted by setting the range with a jvm argument at program start (afaik it defaults to -127 to 128).

Share:
21,420
dido
Author by

dido

Updated on June 13, 2020

Comments

  • dido
    dido almost 4 years

    I'm reading SCJP Java 6 by Kathy Sierra and Bert Bates and this book is confusing me so much. On page 245 they state that the following code below.

    Integer i1 = 1000;
    Integer i2 = 1000;
    if(i1 != i2)
    System.out.println("different objects");
    
    //Prints output
    different objects
    

    Then on the very next page they have the following code

    Integer i3 = 10;
    Integer i4 = 10;
    if(i3 == i4)
    System.out.println("same objects");
    
    //Prints output
    same objects
    

    I'm so confused! When I try this out on my own it seems that you cannot use the == to compare the same way you would use equals() method. Using the == always gives me 'false' even if the Integer variables are set to the same value (i.e. 10). Am I correct? Using the == to compare the same Integer object (with same values) will always result in 'false'