如何解决将包装器类和基元与==运算符进行比较时,类型转换背后的逻辑是什么?
我读到,当需要执行多个操作以执行隐式转换(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
我的理解是编译器尝试用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 Specification的15.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节中的规则,因为i
和d
都是引用类型,而不是数字类型。只有基本类型是数字类型(当然boolean
除外)。
由于无法将Integer
强制转换为Double
,并且不能将Double
强制强制转换为Integer
,因此编译器知道表达式无法为true(忽略两个值均为null
的情况),因此会发生编译类型错误。
当您执行(double) i == d
时,左侧变为数字类型,并且适用15.21.1节中指定的规则。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。