double与Double之间的差异

问题描述 投票:17回答:4

我知道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直接使比较错误。请为我解释。

java double
4个回答
26
投票

cd从技术上讲是两个不同的对象,并且==运算符仅比较引用。

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

另请参见


4
投票

应用于类类型的表达式时,How to properly compare two Integers in Java?总是执行参考比较(==)。所以这行:

JLS section 15.21.3

正在检查System.out.println(c == d); c是否引用相同的对象。我相信Java中的自动装箱总是为dfloat创建一个新对象(整数类型1的情况更加复杂)。因此,doublec引用了不同的对象,因此它打印了d

如果要比较对象是否相等,则需要显式调用false

equals

使用System.out.println(c.equals(d)); ,它改为使用数字等式-如double中指定的。因此,行为上的差异。


1对于整体自动装箱,将缓存“较小”的值-因此自动装箱5(例如)每次都会返回相同的参考。 “ small”的定义是特定于实现的,但是保证在-128到127的范围内。有关详细信息,请参见section 15.21.1的底部。


3
投票

使用section 5.1.7检查2个对象的相等性。 equals()检查2个引用是否引用内存中的同一对象。


2
投票

仅在检查基本类型时,内容检查才对==可靠。对于对象类型,总是最好使用==方法:

equals
© www.soinside.com 2019 - 2024. All rights reserved.