执行以下代码段时,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不同?
答案 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,因为在那里查看的是实际值,而不是快速检查内存地址是否相同。