Java:比较不同的double和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
跟我这么奇怪!!!
所以,如果我们每次使用Double
,我们必须做这样的事情:
private static final double delta = 0.0001; System.out.println(Math.abs(cd) < delta);
我无法解释为什么Double直接比较错误。 请解释一下。
谢谢 :)
c
和d
在技术上是两个不同的对象,而==
运算符只比较引用。
c.equals(d)
更好,因为它比较值,而不是参考。 但仍然不理想。 直接比较浮点值应始终考虑一些误差(epsilon)( Math.abs(c - d) < epsilon
)。
注意:
Integer c = 1; Integer d = 1;
这里比较会产生true
,但这更复杂( Integer
内部缓存,在Integer.valueOf()
JavaDoc中描述):
此方法将始终缓存-128到127(包括端点)范围内的值,并可以缓存此范围之外的其他值。
为什么valueOf()
? 因为此方法隐式用于实现自动装箱:
Integer c = Integer.valueOf(1); Integer d = Integer.valueOf(1);
也可以看看
- Java中奇怪的整数拳击
- 如何正确比较Java中的两个整数?
当应用于类类型的表达式时, ==
将始终执行引用比较( JLS第15.21.3节 )。 所以这一行:
System.out.println(c == d);
正在检查c
和d
是否引用相同的对象。 Java中的自动装箱总是(我相信)为float
和double
创建一个新对象(对于整数类型1 ,情况更复杂)。 因此c
和d
引用不同的对象,因此它打印为false
。
如果要比较对象是否相等,则需要显式调用equals
:
System.out.println(c.equals(d));
使用double
,它使用数字相等 – 如第15.21.1节所述 。 因此行为上的差异。
1对于整体自动装箱,缓存“小”值 – 因此自动装箱5(比如说)每次都会返回相同的参考值。 “小”的定义是特定于实现的,但它保证在-128到127的范围内。有关详细信息,请参见5.1.7节的底部。
使用equals()
检查2个对象的相等性。 ==
检查2个引用是否引用内存中的同一对象。
在检查基元类型时,内容检查仅对==
可靠。 对于对象类型,最好使用equals
方法:
c.equals(d)