Java:比较不同的double和Double

hqt*_*hqt 16 java double

我知道这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
Run Code Online (Sandbox Code Playgroud)

对我这么奇怪!!!

所以,如果我们Double每次使用,我们必须做这样的事情:

private static final double delta = 0.0001;
System.out.println(Math.abs(c-d) < delta); 
Run Code Online (Sandbox Code Playgroud)

我无法解释为什么Double直接比较错误.请解释一下.

谢谢 :)

Tom*_*icz 25

cd从技术上讲,它们是两个不同的对象,==运算符只比较引用.

c.equals(d)
Run Code Online (Sandbox Code Playgroud)

更好,因为它比较值,而不是参考.但仍然不理想.直接比较浮点值应始终考虑一些错误(epsilon)(Math.abs(c - d) < epsilon).

注意:

Integer c = 1;
Integer d = 1;
Run Code Online (Sandbox Code Playgroud)

这里比较会产生true,但这更复杂(Integer内部缓存,在JavaDoc中Integer.valueOf()描述):

此方法将始终缓存-128到127(包括端点)范围内的值,并可以缓存此范围之外的其他值.

为什么valueOf()?因为此方法隐式用于实现自动装箱:

Integer c = Integer.valueOf(1);
Integer d = Integer.valueOf(1);
Run Code Online (Sandbox Code Playgroud)

也可以看看


Jon*_*eet 6

当应用于类类型的表达式时,==始终执行引用比较(JLS 第 15.21.3 节)。所以这一行:

System.out.println(c == d); 
Run Code Online (Sandbox Code Playgroud)

正在检查cd引用相同的对象。Java 中的自动装箱总是(我相信)为floatand创建一个新对象double(整数类型1的情况更复杂)。因此candd引用不同的对象,所以它打印false.

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

System.out.println(c.equals(d));
Run Code Online (Sandbox Code Playgroud)

使用double,它使用数字相等代替 - 如第 15.21.1 节中所述。因此,行为上的差异。


1对于完整的自动装箱,“小”值被缓存 - 所以自动装箱 5(比如说)每次都会返回相同的引用。“小”的定义是特定于实现的,但保证在 -128 到 127 的范围内。有关详细信息,请参阅第 5.1.7 节的底部。