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,
intandInteger. You’re getting anIntegerfromvalueOfon the right hand side, of course. -
After the conversion, you’re comparing two primitive
intvalues. Comparison happens just as you would expect it to with respect to primitives, so you wind up comparing128and128.