长和双比较(==)的行为有所不同

时间:2020-01-30 14:01:41

标签: java

执行以下代码段时,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

为什么Double ==的行为与Long不同?

1 个答案:

答案 0 :(得分:3)

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

您将在此处创建对对象的两个引用,并使用Java的自动装箱行为实例化两个对象。

Java在v1和v2的池中重复使用了相同的Long对象实例,而Doubles并没有使用池来记住值,如在此翔实的博客文章https://gerardnico.com/code/type/autoboxing中所读到的

以下是Java 5的一些规则:

自动装箱为Boolean和Byte总是从池中返回一个对象
自动装箱至Char,Short,Integer和Long会从 自动装箱的值介于-128和127(含)之间时缓冲池
自动为Float和Double装箱不会使用游泳池,并且总是 返回一个新对象

然后您的代码将通过自动装箱(某些池是Java用于缓存某些值的池的可视化):

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);

这意味着d1和d2不是相等的实例,因此它们在==
中不相等 这意味着v1和v2是相等的实例,因此它们在==

中相等

v1.equals返回true,因为在那里查看的是实际值,而不是快速检查内存地址是否相同。

相关问题