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'

6 Answers
6

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 above 128 are not interned, hence Integer(1000) objects are not equal to each other.

Wow! I just saw that too. Why?? That's so confusing. What is the reasoning behind this?
–
didoApr 14 '12 at 0:38

5

note that only the object obtained from literals, autoboxing and Integer.valueOf() are interned objects while those constructed with new Integer are always distinct objects
–
ratchet freakApr 14 '12 at 0:38

I seem to remember that also goes for small Strings, but am not sure whether this is true and if so, what is considered a small String. Do you know anything about that?
–
G. BachApr 14 '12 at 0:38

@G.Bach No, that has nothing to do with size. String constants are interned and you can call intern on your string variables for the same effect, that's all. And the why is simple: We need to store string constants somewhere anyhow and for small integers it's just a performance/memory optimization
–
VooApr 14 '12 at 0:45

1

@dido One of the reasons behind interning integers is an attempt to save memory and to a certain extent - to save time as well. When Integer objects are used as keys in hash maps or as objects in hash sets, the percentage of small integers is disproportionally large. By interning them you can skip re-allocation of memory to hold identical copies of immutable objects that are equal to each other, and let the equality compare finish faster by checking reference equality first. Best of all, it hardly costs you anything in terms of CPU cycles, so it was an easy decision to make.
–
dasblinkenlightApr 14 '12 at 0:49

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.

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.

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.

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.

When the Java == operator is used to compare anything other than primitive types, it checks for referential equality; this applies even when the things being compared are wrapped primitives. Further, the valueOf method and compiler-generated autoboxing statement are generally free to arbitrarily return a new object which will not be reference-equal to any other previously-existing reference, or to return a reference to an existing object (which would, of course, be reference-equal to any pre-existing reference identifying the same object). Implementations are required to maintain a "pool" of Integer instances for values -128 to 127, such that all calls to Integer.valueOf on any particular number within that range will return references to the same object, but other than that an implementation would be free to do something like

I don't particularly expect Java implementations to do something like that, since in many cases the "cache hit" ratio could be near 0% and the extra time spent looking for instances in the cache would be wasted. Nonetheless, there is never any guarantee that a reference returned by instanceOf won't match some previous reference returned by that method (even if it doesn't match the last reference returned by that method, some caching algorithms might possibly cause it to return an earlier reference, especially if the pool is shared by multiple threads without locking. The lack of locking will never cause the code to return anything other than a reference to an integer with the correct value, but could cause unpredictable variations in which returned references compare equal). Only reference to Integer objects created directly using the constructor new Integer(n) are guaranteed to be unique; code which expects any reference returned by valueOf to not match any reference returned by valueOf, without having actually observed that it does not match, should be considered broken.

String comparison and integer comparison using == and != gives boolean results not as we expect.So be careful and make sure the possible unknown outcomes do not hinder the performance , reliability and accuracy of your software.