在 Java 中比较双打会产生奇怪的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5230642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing doubles in Java gives odd results
提问by Simeon
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.
我肯定这在某种程度上与自动装箱有关,但我真的不知道为什么0
在使用==
运算符和.equals
调用时会以不同的方式装箱。
Doesn't this implicitly violate the equals
contract ?
这不是暗中违反equals
合同吗?
* 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: whyis 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.
感谢您的快速答复。我认为它的装箱方式不同,真正的问题是:为什么它的装箱方式不同?我的意思是,这将是更直观,如果d == 0d
不是d.equals(0d)
非常直观和预期,但是如果d == 0
它看起来像一个Integer
是true
不是“直觉”d.equals(0)
也应该是真实的。
回答by Jigar Joshi
just change it to
只需将其更改为
System.out.println(d.equals(0d)); // is false ?! now true
You were comparing double with Integer
0
您正在将 double 与Integer
0进行比较
Under the cover
在封面下
System.out.println(d.equals(0)); // is false ?!
0
will be autoboxed to Integer
and an instance of Integer will be passed to equals()
method of Double
class, where it will compare like
0
将被自动装箱,Integer
并且 Integer 的实例将被传递给类的equals()
方法Double
,在那里它会比较像
@Override
public boolean equals(Object object) {
return (object == this)
|| (object instanceof Double)
&& (doubleToLongBits(this.value) == doubleToLongBits(((Double) object).value));
}
which is going to return falseof course.
这当然会返回false。
Update
更新
when you do comparison using ==
it compares values so there is no need to autobox , it directly operates on value. Where equals()
accepts Object
so if you try to invoke d1.equals(0)
, 0
is not Object so it will perform autoboxing and it will pack it to Integer which is an Object.
当您使用==
它进行比较时,它会比较值,因此无需自动装箱,它直接对值进行操作。如果您尝试调用,那么equals()
接受的地方不是 Object,因此它将执行自动装箱,并将其打包为 Integer,这是一个 Object。Object
d1.equals(0)
0
回答by fortran
Number
objects only equal to numbers with the same value if they are of the same type. That is:
Number
如果对象类型相同,则对象仅等于具有相同值的数字。那是:
new Double(0).equals(new Integer(0));
new BigInteger("0").equals(new BigDecimal("0"));
and similar combinations are all false.
而类似的组合都是假的。
In your case, the literal 0
is boxed into an Integer
object.
在您的情况下,文字0
被装箱到一个Integer
对象中。
回答by duedl0r
It's probably worth noting that you should compare floating point numbers like this:
可能值得注意的是,您应该像这样比较浮点数:
|x - y| < ε, ε very small
回答by Suraj Chandran
d.equals(0)
: 0
is an int
. The Double.equals()
code will return true only for Double
objects.
d.equals(0)
:0
是一个int
。该Double.equals()
代码将仅对Double
对象返回 true 。
回答by Peter Lawrey
When you perform
当你执行
d == 0
this is upcast to
这是向上看
d == 0.0
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.
但是,没有自动装箱的向上转换规则,即使有 equals(Object) 也不会给出您想要 Double 而不是 Integer 的命中。