I read that compiler refuses to use auto boxing/unboxing when there is more than one operation needed in order to perform implicit conversion (int -> double -> Double or Integer -> int -> double). It's stil rather confusing
Integer i = 2;
Double d = 2.0;
System.out.println(i == d); // COMPILE TIME ERROR
// fix
System.out.println( (double) i == d); // OK: true
My understanding is that the compiler tries to unwrap i with Integer.intValue(). Since it takes more than one step to convert Integer to double (Integer -> int -> double) compiler refuses to do it implicitly, so we need to "help him" by using explicit type conversion, which will reduce the number of steps. Is it correct?
Integer i = 2;
double d = 2.0;
System.out.println(i == d); // OK: true
In this example it clearly takes more than one step for the compiler to perform conversion (Integer -> int -> double). How come it doesn't complain?
I'm aware that one must use equals() method over ==
The answer can be found in the Java Language Specification, in section 15.21. Equality Operators:
Section 15.21.1. Numerical Equality Operators
==and!=says:Section 15.21.3. Reference Equality Operators
==and!=says:Without a cast, the
i == dexpression must follow the rules in section 15.21.3, because bothianddare reference types, not numeric types. Only the primitive types are numeric types (exceptbooleanof course).Since an
Integercannot be cast to aDouble, and aDoublecannot be cast to anInteger, the compiler knows that it is impossible for the expression to be true (ignoring the case where both values arenull), so a compile-type error occurs.When you do
(double) i == d, then the left-hand side becomes a numeric type, and the rules specified in section 15.21.1 applies.