How != and == operators work on Integers in Java?
Solution 1
Integers are cached for values between -128 and 127 so Integer i = 127
will always return the same reference. Integer j = 128
will not necessarily do so. You will then need to use equals
to test for equality of the underlying int
.
This is part of the Java Language Specification:
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
But 2 calls to Integer j = 128
might return the same reference (not guaranteed):
Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.
Solution 2
Because small integers are interned in Java, and you tried the numbers on different sides of the "smallness" limit.
Solution 3
There exist an Integer object cache from -128 and up to 127 by default. The upper border can be configured. The upper cache border can be controlled by VM option -XX:AutoBoxCacheMax=<size>
You are using this cache when you use the form:
Integer i1 = 127;
or
Integer i1 = Integer.valueOf(127);
But when you use
Integer i1 = new Integer(127);
then you're guaranteed to get a new uncached object. In the latter case both versions print out the same results. Using the cached versions they may differ.
Comments
-
Debadyuti Maiti almost 2 years
The following code seemed really confusing to me since it provided two different outputs.The code was tested on jdk 1.7.
public class NotEq { public static void main(String[] args) { ver1(); System.out.println(); ver2(); } public static void ver1() { Integer a = 128; Integer b = 128; if (a == b) { System.out.println("Equal Object"); } if (a != b) { System.out.println("Different objects"); } if (a.equals(b)) { System.out.println("Meaningfully equal."); } } public static void ver2() { Integer i1 = 127; Integer i2 = 127; if (i1 == i2) { System.out.println("Equal Object"); } if (i1 != i2){ System.out.println("Different objects"); } if (i1.equals(i2)){ System.out.println("Meaningfully equal"); } } }
Output:
[ver1 output]
Different objects
Meaningfully equal.[ver2 output]
Equal Object
Meaningfully equalWhy the == and != testing produces different results for ver1() and ver2() for same number much less than the Integer.MAX_VALUE? Can it be concluded that == checking for numbers greater than 127 (for wrapper classes like Integer as shown in the code) is totally waste of time?
-
fgb about 12 yearsThe constructor doesn't use caching though. Try: System.out.println(new Integer(2) == new Integer(2))
-
Fabian Barney about 12 years
new Integer(127)
will never return the same reference. In fact, it guarantees to always create a new object. But when auto-boxing is used like inInteger i = 127;
then the cache is used. Btw the upper border 127 is not fixed but a minimum. It can be configured to a larger value but not lower. -
Sergey Kalinichenko about 12 years@downvoter, would you care to elaborate on your vote?
-
atamanroman about 9 yearsNice to know. Please don't do that in production.