I have no idea why these lines of code return different values:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
The output is:
true
false
true
Why does the first one return true
and the second one return false
? Is there something different that I don't know between 127
and 128
? (Of course I know that 127
< 128
.)
Also, why does the third one return true
?
I have read the answer of this question, but I still didn't get how it can return true
, and why the code in second line returns false
.
There's a striking difference here.
valueOf
is returning an Integer
object, which may have its values cached between -128 and 127. This is why the first value returns true
- it's cached - and the second value returns false
- 128 isn't a cached value, so you're getting two separate Integer
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 to true
, even if the parsed values are equivalent (case in point: Integer.valueOf(128) == Integer.valueOf(128)
). You must use equals()
instead.
parseInt
is returning a primitive int
. This is why the third value returns true
- 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
and Integer
. You're getting an Integer
from valueOf
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 comparing 128
and 128
.