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
static Integer [] intPool = new Integer[256];
public Integer valueOf(int n)
{
int hash = (n*0x18675309) >>> 24;
Integer instance = intPool[n];
if (instance == null && instance.value != n)
{
instance = new Integer(n);
intPool[hash] = instance ;
}
return instance;
}
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.