I want to compare two Long objects values using if
conditions. When these values are less than 128, the if
condition works properly, but when they are greater than or equal to 128, comparison fails.
Example:
Long num1 = 127;
Long num2 = 127;
if (num1 == num2) {
// Works ok
}
Comparison on the code above works properly, but fails in the code below:
Long num1 = 128;
Long num2 = 128;
if (num1 == num2) {
// Does NOT work
}
Why is there a problem in comparing Long variables with values greater than 127? If the variables data types are changed to long primitives, then the comparisons work for all cases.
TL;DR
Java caches boxed Integer instances from
-128
to127
. Since you are using==
to compare objects references instead of values, only cached objects will match. Either work withlong
unboxed primitive values or use.equals()
to compare yourLong
objects.Long (pun intended) version
Java caches Integer objects instances from the range -128 to 127. That said:
127
(cached), the same object instance will be pointed by all references. (N variables, 1 instance)128
(not cached), you will have an object instance pointed by every reference. (N variables, N instances)That's why this:
Outputs this:
For the 127L value, since both references (val1 and val2) point to the same object instance in memory (cached), it returns
true
.On the other hand, for the 128 value, since there is no instance for it cached in memory, a new one is created for any new assignments for boxed values, resulting in two different instances (pointed by val3 and val4) and returning
false
on the comparison between them.That happens solely because you are comparing two
Long
object references, notlong
primitive values, with the==
operator. If it wasn't for this Cache mechanism, these comparisons would always fail, so the real problem here is comparing boxed values with==
operator.Changing these variables to primitive
long
types will prevent this from happening, but in case you need to keep your code usingLong
objects, you can safely make these comparisons with the following approaches:(Proper null checking is necessary, even for castings)
IMO, it's always a good idea to stick with .equals() methods when dealing with Object comparisons.
Reference links: