Why do == comparisons with Integer.valueOf(String) give different results for 127 and 128?

DnR picture DnR · Jan 2, 2014 · Viewed 17.1k times · Source

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.

Answer

Makoto picture Makoto · Jan 2, 2014

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.