Long and Double comparison (==) behaves differently

João Pedro Schmitt :

When executing the following code snippet it behaves differently for Double.

Long v1 = 1L;
Long v2 = 1L;
Double d1 = 1.0;
Double d2 = 1.0;

System.out.println(v1 == v2); // Prints true
System.out.println(d1 == d2); // Prints false

System.out.println(v1.equals(v2)); // Prints true
System.out.println(d1.equals(d2)); // Prints true

Why Double == behaves differently from Long?

Tschallacka :
Long v1 = 1L;
Long v2 = 1L;
Double d1 = 1.0;
Double d2 = 1.0;

You are creating two references to objects here, and instantiating two objects with autoboxing behaviour of Java.

Java re-uses the same Long object instance from a pool for v1 and v2, The Doubles do not use a pool for remembering values, as can be read in this informative blog entry https://gerardnico.com/code/type/autoboxing

Here are some rules as with Java 5 :

autoboxing to Boolean and Byte always returns an object from the pool
autoboxing to Char, Short, Integer and Long returns an object from the pool when the autoboxed value is between -128 and 127 (inclusive)
autoboxing of Float and Double does not use the pool and always returns a new object

Your code becomes then with autoboxing(some pool is a visualisation of the pool java uses to cache certain values):

class SomePoolJavaUses {
   static Long _l1 = new Long(1L);
   static Long _l2 = new Long(2L);
   static Long _l3 = new Long(3L);
   ...
}

Long v1 = SomePoolJavaUses._l1;
Long v2 = SomePoolJavaUses._l1;
Double d1 = new Double(1.0);
Double d2 = new Double(1.0);

This means that d1 and d2 are not equal instances, so they are not equal in ==
This means that v1 and v2 are equal instance, so they are equal in ==

the v1.equals returns true, because there is being looked at the actual value there instead of a quick check if the memory addresses are the same.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=6039&siteId=1