Still the question is not clear? Let's rephrase it in this way: -
Why two integer objects with same value are not equal when using auto-boxing? I mean, let say - Integer i1 = 128, and Integer i2 = 128; i1 and i2 are not equal using ‘==’ operator. On the other hand 127 is equals to 127 i.e. 127 == 127 Why?
Below is the snippet of the java program: -
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
if (i1 == i2) { // true
System.out.println("i1 and i2 are equal");
} else {
System.out.println("i1 and i2 are not equal");
}
if (i3 == i4) { // false
System.out.println("i3 and i4 are equal");
} else {
System.out.println("i3 and i4 are not equal");
}
O/P (Output is): -
i1 and i2 are equal
i3 and i4 are not equal
Why i3 is not equal to i4?
Instances of "Integer" are not necessarily unique. An Integer instance is an object; you can think of your 'i3' and 'i4' variables as pointers to a chunk of RAM. That chunk of RAM wraps around an 'int' value.
Java 5 implements 'auto-boxing', a syntaxic feature which tries to automatically fill the gap between the 'int' type (the 32-bit signed integer) and the 'Integer' type (the class where every instance contains an 'int' value).
The key to understanding this is that the JVM uses a process called "boxing" (or "auto-boxing") when converting an int (like 127) to an Integer object. This involves calling the Integer.valueOf(127) method.
The JavaDoc:java.lang.Integer#valueOf(int)says: "Returns a Integer instance representing the specified int value.
When you write this:
Integer x = 128;
What actually gets compiled is:
Integer x = Integer.valueOf(128);
Where Integer.valueOf() is a static method which returns an Integer instance containing the provided 'int' value. Integer.valueOf() may return the same instance twice, or not; in practice, the implementation of Integer.valueOf() often caches instances for small integers, e.g. those from -128 to 127. For other values, it performs a simple 'new Integer(val)' and returns that, hence a new instance every time. This is what you observe.
If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values."
Integer.valueOf(...) caches int values specifically from -128 to 127. It means if the integer value comes in the range of -128 to 127, then a new instance creation is not required, the valueOf() get the existing instance from the cache if the object is already created, that is, the cached object will be returned.
What that means is that the valueOf() method has a cache of Integer objects, and if the primitive being boxed is in that range, the cached object is returned. It just so happens that 127 are in that range, but 128 is not. So i1 and i2 are the same object, while i3 and j4 are not.
When you use '==' on two 'Integer' values, you are comparing the pointers (the "references" in Java terminology). If two pointers are equal then they point to the same instance, wrapping around a unique value. But if two pointers are distinct, it just means that they point to distinct instances, _not_ that those instances contain distinct 'int' values.
Operators are not overloaded in Java (well, at least not to that point). If you want a numerical comparison then you have to get the numbers themselves, not the wrappers:
Integer a128 = 128;
Integer b128 = 128;
if (a128 == b128) {
/* you have compared the pointers */
}
if (a128.intValue() == b128.intValue()) {
/* you have compared the numerical values */
}
Auto-boxing blurs the line a bit between class instances and plain integers, but that does not make integers objects in their own right. The point of auto-boxing is to ease the syntaxic use of integers as keys or values in collections (List, Map...).
So, in order to save memory when primitive types are boxed into the wrapper types, the JVM allocates memory and creates a new object. But for some special cases, the JVM reuses the same object, two instances of the following wrapper objects will always be == when their primitive values are the same.
- Boolean
- Byte
- Character from \u0000 to \u007f (7f is 127 in decimal)
- Short and Integer from -128 to 127
Conclusion: - This new feature in J2SE 5.0 has both advantanges and disadvantess, it all depends on where and how are we using the feature. It is recommended by SUN to use them only when there is an “impedance mismatch” between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
References: -