微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将包装器类和基元与==运算符进行比较时,类型转换背后的逻辑是什么?

如何解决将包装器类和基元与==运算符进行比较时,类型转换背后的逻辑是什么?

我读到,当需要执行多个操作以执行隐式转换(int -> double -> DoubleInteger -> 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

我的理解是编译器尝试用i解开Integer.intValue()。由于将Integer转换为double(Integer-> int-> double需要花费一个以上的步骤,因此编译器拒绝隐式地执行此操作,因此我们需要使用来“帮助他”显式类型转换,这将减少步骤数。正确吗?

Integer i = 2;
double d = 2.0;
System.out.println(i == d); // OK: true

在此示例中,显然编译器需要执行多个步骤(Integer -> int -> double)。怎么不抱怨?

我知道必须在equals()上使用==方法

解决方法

答案可以在Java Language Specification15.21. Equality Operators部分中找到:

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

15.21.1. Numerical Equality Operators == and !=节说:

如果相等运算符的操作数都是数字类型,或者一个是数字类型,而另一个可转换(§5.1.8)到数字类型,则对操作数执行二进制数字提升({{3 }}。

§5.6节说:

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

如果无法通过强制转换(15.21.3. Reference Equality Operators == and !=)将一个操作数的类型转换为另一个操作数的类型,则将发生编译时错误。这两个操作数的运行时值必然不相等(忽略两个值均为null的情况)。

没有强制类型转换,i == d表达式必须遵循15.21.3节中的规则,因为id都是引用类型,而不是数字类型。只有基本类型是数字类型(当然boolean除外)。

由于无法将Integer强制转换为Double,并且不能将Double强制强制转换为Integer,因此编译器知道表达式无法为true(忽略两个值均为null的情况),因此会发生编译类型错误。

当您执行(double) i == d时,左侧变为数字类型,并且适用15.21.1节中指定的规则。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。