Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the cause of this strange Java behavior?

Tags:

java

jvm

bytecode

I wanted to test the '==' operator on Longs 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 Longs 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 nullcheck 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

like image 267
Matyas Avatar asked Aug 14 '12 17:08

Matyas


3 Answers

This is the result of auto-boxing. See Long.valueOf().

like image 125
jtahlborn Avatar answered Nov 01 '22 05:11

jtahlborn


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.

like image 3
Nestor Avatar answered Nov 01 '22 04:11

Nestor


-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.

like image 1
Nandkumar Tekale Avatar answered Nov 01 '22 03:11

Nandkumar Tekale