我知道Double
是一个包装类,并且它包装double
号。今天,我看到了另一个主要区别:
double a = 1.0;
double b = 1.0;
Double c = 1.0;
Double d = 1.0;
System.out.println(a == b); // true
System.out.println(c == d); // false
我真奇怪!
因此,如果我们每次使用Double
,我们都必须这样做:
private static final double delta = 0.0001;
System.out.println(Math.abs(c-d) < delta);
我无法解释为什么Double直接使比较错误。请为我解释。
c
和d
从技术上讲是两个不同的对象,并且==
运算符仅比较引用。
c.equals(d)
更好,因为它比较值而不是引用。但是仍然不理想。直接比较浮点值应始终将一些误差(ε)考虑在内(Math.abs(c - d) < epsilon
)。
注意:
Integer c = 1;
Integer d = 1;
这里的比较将产生true
,但是更复杂(Integer
内部缓存,在JavaDoc of Integer.valueOf()
中描述):
此方法将始终缓存-128至127(包括)范围内的值,并且可能缓存该范围之外的其他值。
为什么Integer.valueOf()
?因为此方法隐式用于实现自动装箱:
valueOf()
Integer c = Integer.valueOf(1);
Integer d = Integer.valueOf(1);
应用于类类型的表达式时,How to properly compare two Integers in Java?将总是执行参考比较(==
)。所以这行:
JLS section 15.21.3
正在检查System.out.println(c == d);
和c
是否引用相同的对象。我相信Java中的自动装箱总是为d
和float
创建一个新对象(整数类型1的情况更加复杂)。因此,double
和c
引用了不同的对象,因此它打印了d
。
如果要比较对象是否相等,则需要显式调用false
:
equals
使用System.out.println(c.equals(d));
,它改为使用数字等式-如double
中指定的。因此,行为上的差异。
1对于整体自动装箱,将缓存“较小”的值-因此自动装箱5(例如)每次都会返回相同的参考。 “ small”的定义是特定于实现的,但是保证在-128到127的范围内。有关详细信息,请参见section 15.21.1的底部。
使用section 5.1.7检查2个对象的相等性。 equals()
检查2个引用是否引用内存中的同一对象。
仅在检查基本类型时,内容检查才对==
可靠。对于对象类型,总是最好使用==
方法:
equals