比较 Java 中的双精度数会得到奇怪的结果
我真的无法理解为什么会发生以下情况:
Double d = 0.0;
System.out.println(d == 0); // is true
System.out.println(d.equals(0)); // is false ?!
然而,这按预期工作:
Double d = 0.0;
System.out.println(d == 0.0); // true
System.out.println(d.equals(0.0)); // true
我确信这在某种程度上与自动装箱有关,但我真的不知道为什么0==
运算符和调用 .equals
时,code> 的装箱方式会有所不同。
这不是隐含地违反了equals
契约吗?
* It is reflexive: for any non-null reference value * x, x.equals(x) should return * true.
编辑:
感谢您的快速答复。我认为它的装箱方式不同,真正的问题是:为什么它的装箱方式不同?我的意思是,如果 d == 0d
比 d.equals(0d)
更直观且符合预期,但是如果 d == 0
code> 看起来像 Integer
是 true
而“直观地”d.equals(0)
也应该是 true。
I really can'get my head around why the following happens:
Double d = 0.0;
System.out.println(d == 0); // is true
System.out.println(d.equals(0)); // is false ?!
This however works as expected:
Double d = 0.0;
System.out.println(d == 0.0); // true
System.out.println(d.equals(0.0)); // true
I'm positive that this is related to autoboxing in some way, but I really don't know why 0
would be boxed differently when the ==
operator is used and when .equals
is called.
Doesn't this implicitly violate the equals
contract ?
* It is reflexive: for any non-null reference value * x, x.equals(x) should return * true.
EDIT:
Thanks for the fast answers. I figured that it is boxed differently, the real question is: why is it boxed differently ? I mean that this would be more intuitive if d == 0d
than d.equals(0d)
is intuitive and expected, however if d == 0
which looks like an Integer
is true
than 'intuitively' d.equals(0)
should also be true.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
只需将其更改为
You were Comparison double with
Integer
0Under the cover
0
will be autoboxed toInteger
and an Integer 的实例将被传递给 Double 类的 equals() 方法,在该方法中它将进行比较,当然会返回 false 。
更新
当您使用
==
进行比较时,它会比较值,因此不需要 autobox ,它直接对值进行操作。其中equals()
接受Object
因此,如果您尝试调用d1.equals(0)
,则0
不会对象,因此它将执行自动装箱并将其打包为作为对象的 Integer。just change it to
You were comparing double with
Integer
0Under the cover
0
will be autoboxed toInteger
and an instance of Integer will be passed toequals()
method ofDouble
class, where it will compare likewhich is going to return false of course.
Update
when you do comparison using
==
it compares values so there is no need to autobox , it directly operates on value. Whereequals()
acceptsObject
so if you try to invoked1.equals(0)
,0
is not Object so it will perform autoboxing and it will pack it to Integer which is an Object.Number
对象仅等于具有相同值的数字(如果它们属于相同类型)。即:和 类似的组合都是假的。
在您的情况下,文字
0
被装箱到Integer
对象中。Number
objects only equal to numbers with the same value if they are of the same type. That is:and similar combinations are all false.
In your case, the literal
0
is boxed into anInteger
object.可能值得注意的是,您应该像这样比较浮点数:
It's probably worth noting that you should compare floating point numbers like this:
d.equals(0)
:0
是一个int
。Double.equals()
代码仅对Double
对象返回 true。d.equals(0)
:0
is anint
. TheDouble.equals()
code will return true only forDouble
objects.当您执行
此操作时,会向上转型
,但是没有自动装箱的向上转型规则,即使有 equals(Object) 也不会给出您想要的 Double 而不是 Integer 的命中。
When you perform
this is upcast to
however there are no upcasting rules for autoboxing and even if there were equals(Object) gives no hits that you want a Double instead of an Integer.