When you compile a number literal in Java and assign it to a Integer (capital I
) the compiler emits:
Integer b2 =Integer.valueOf(127)
This line of code is also generated when you use autoboxing.
valueOf
is implemented such that certain numbers are "pooled", and it returns the same instance for values smaller than 128.
From the java 1.6 source code, line 621:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
The value of high
can be configured to another value, with the system property.
-Djava.lang.Integer.IntegerCache.high=999
If you run your program with that system property, it will output true!
The obvious conclusion: never rely on two references being identical, always compare them with .equals()
method.
So b2.equals(b3)
will print true for all logically equal values of b2,b3.
Note that Integer
cache is not there for performance reasons, but rather to conform to the JLS, section 5.1.7; object identity must be given for values -128 to 127 inclusive.
Integer#valueOf(int) also documents this behavior:
this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
You're comparing Integer
values, which are references. You're coming up with those references via autoboxing. For some values (guaranteed for -128 to 127) the JRE maintains a cache of Integer
objects. For higher values, it doesn't. From section 5.1.7 of the JLS:
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.
Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.
This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. 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.
Moral: don't compare Integer
references when you're interested in the underlying int
values. Use .equals()
or get the int
values first.
Best Answer
There's a striking difference here.
valueOf
is returning anInteger
object, which may have its values cached between -128 and 127. This is why the first value returnstrue
- it's cached - and the second value returnsfalse
- 128 isn't a cached value, so you're getting two separateInteger
instances.It is important to note that you are comparing references with
Integer#valueOf
, and if you are comparing a value that is larger than what the cache supports, it will not evaluate totrue
, even if the parsed values are equivalent (case in point:Integer.valueOf(128) == Integer.valueOf(128)
). You must useequals()
instead.parseInt
is returning a primitiveint
. This is why the third value returnstrue
-128 == 128
is evaluated, and is of course,true
.Now, a fair bit happens to make that third result
true
:An unboxing conversion occurs with respect to the equivalence operator you're using and the datatypes you have - namely,
int
andInteger
. You're getting anInteger
fromvalueOf
on the right hand side, of course.After the conversion, you're comparing two primitive
int
values. Comparison happens just as you would expect it to with respect to primitives, so you wind up comparing128
and128
.