I wanted to test the '==' operator on Long
s and this is what I've found: the following code:
public static void main(final String[] args) {
final Long n = 0L;
final Long m = 0L;
System.out.println(n + " == " + m + " : " + (n == m));
final Long a = 127L;
final Long b = 127L;
System.out.println(a + " == " + b + " : " + (a == b));
final Long A = 128L;
final Long B = 128L;
System.out.println(A + " == " + B + " : " + (A == B));
final Long x = -128L;
final Long y = -128L;
System.out.println(x + " == " + y + " : " + (x == y));
final Long X = -129L;
final Long Y = -129L;
System.out.println(X + " == " + Y + " : " + (X == Y));
}
outputs:
0 == 0 : true
127 == 127 : true
128 == 128 : false
-128 == -128 : true
-129 == -129 : false
The only explanation I could come up with was that the JVM stores all long
values inside [-128, 127]
in the Perm space, and gives their address to Long
s and to everything outside the above range it creates a new allocation for each static value met in the code.
Am I close to being right? In what situations do we have to be aware of similar behaviors?
PS. I know I should use a null
check and then .equals()
to compare objects, but I was curious if anyone knew the answer.
EDIT
After jtahlborn's answer who gave me the keyword auto-boxing I've found this great article with the well-documented answer
This is the result of auto-boxing. See Long.valueOf().
Long
has a internal cache for values from -128 to 127. if you create Long
by Long.valueOf(long)
method or autoboxing in this interval you always receive the same object for equals values. That's why '==' work for 0, 127 and -128 in your example.
If you create Long
outside [-128, 127] then always will be created new instance if Long
object.
That's why '==' don't work for 128 and -129.
Have a look to Long.valueOf(long)
source code.
-128 to +127
will be evaluated to true using ==
operator if you are comparing object references
. The Long values(from -128 to +127) are put in a cache and returned multiple times, while higher and lower numbers generate new Long
each time.
This is apllicable to primitive wrapper classes Integer, Float
too. Try it for Integer and Float.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With