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 ?
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.
just change it to
System.out.println(d.equals(0d)); // is false ?! now true
You were comparing double with Integer
0
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
@Override
public boolean equals(Object object) {
return (object == this)
|| (object instanceof Double)
&& (doubleToLongBits(this.value) == doubleToLongBits(((Double) object).value));
}
which is going to return false of course.
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.
It's probably worth noting that you should compare floating point numbers like this:
|x - y| < ε, ε very small
d.equals(0)
: 0
is an int
. The Double.equals()
code will return true only for Double
objects.
Number
objects only equal to numbers with the same value if they are of the same type. That is:
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.