Cache Long in Java

1. Compare two Java Strings
In Java, if you want to compare two String, you know you should use equals instead of ==. To be more specific, here is the normal code to compare two String:

String s1 = "abc"; String s2 = "abc"; s1.equals(s2); // true s1 == s2 // false; the == checks if s1 and s2 refer to the same object, which is not in this case.

2. Compare two Long
Long class is a wrappers of the primitive type long. The Long class contains a field long which is the value of a Long object and provides user with method to convert a Long object to String.

Comparing two Long should be the same as comparing two String. However, there is something interesting coming up while comparing two Long:

Long n1 = 100L; Long n2 = 100L; Long n3 = 1000L; Long n4 = 1000L; n1 == n2 ; // surprisingly, it returns true n3 == n4; // false, as expected

How can comparing n1 and n2 with == returns true and n3 and n4 returns false. What I expected was they should all returns false.

3. Explanation
It turns out that when we work on Long, there is an array of Long objects from -128 to 127 cached. So, anytime we get a Long of value between -128 and 127, such as Long n1 = 100L;, instead of creating a new Long object, it is grasped from cached.

Source code of the Java Long class:

private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }

That is why comparing n1 and n2 returns true. n1 and n2 are actually pointing to the same object. On the other hand, n3 and n4 point to different objects, so the comparison returns false.

The same caching mechanism is applied to Integer, Byte, Character and Short as well. Overall, using == for comparing two Long values is deceptive and we should never use it.

Read More Post