Java 当使用==运算符比较包装类和原语时,类型转换背后的逻辑是什么?

Java 当使用==运算符比较包装类和原语时,类型转换背后的逻辑是什么?,java,wrapper,autoboxing,type-promotion,Java,Wrapper,Autoboxing,Type Promotion,我读到编译器拒绝使用自动装箱/取消装箱,因为执行隐式转换需要多个操作(int->double->double或Integer->int->double)。这仍然相当令人困惑 Integer i = 2; Double d = 2.0; System.out.println(i == d); // COMPILE TIME ERROR // fix System.out.println( (double) i == d); // OK: true 我的理解是编译器试图用Integer.int

我读到编译器拒绝使用自动装箱/取消装箱,因为执行隐式转换需要多个操作(
int->double->double
Integer->int->double
)。这仍然相当令人困惑

Integer i = 2;
Double d = 2.0;
System.out.println(i == d); // COMPILE TIME ERROR

// fix

System.out.println( (double) i == d); // OK: true
我的理解是编译器试图用
Integer.intValue()
打开
i
。由于将整数转换为双精度(
Integer
->
int
->
double
)需要多个步骤,所以编译器拒绝隐式执行此操作,因此我们需要使用显式类型转换来“帮助他”,这将减少步骤数。对吗

Integer i = 2;
double d = 2.0;
System.out.println(i == d); // OK: true
在本例中,编译器执行转换显然需要多个步骤(
Integer->int->double
)。为什么它不抱怨


我知道必须使用
equals()
方法,而不是
=

答案可以在中的部分找到:

运算符==(等于)和!=(不等于)称为相等运算符

该节说:

如果相等运算符的操作数都是数字类型,或者一个是数字类型,另一个可转换为数字类型(),则对操作数()执行二进制数字升级

该节说:

如果相等运算符的操作数都是引用类型或null类型,则该操作为对象相等

如果无法通过强制转换()将任一操作数的类型转换为另一个操作数的类型,则这是编译时错误。两个操作数的运行时值必然不相等(忽略两个值均为
null
的情况)。

如果没有强制转换,
i==d
表达式必须遵循第15.21.3节中的规则,因为
i
d
都是引用类型,而不是数字类型。只有基元类型是数字类型(当然,除了
布尔型

由于
整数
不能转换为
双精度
双精度
不能转换为
整数
,编译器知道表达式不可能为真(忽略两个值均为
null
)的情况,因此会发生编译类型错误

如果执行
(double)i==d
,则左侧将变为数字类型,并且第15.21.1节中指定的规则适用