Using == operator in Java to compare wrapper objects
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).
dido
Updated on June 13, 2020Comments
-
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'