前几天,我因三元运算符中意外的类型转换而遇到了一个非常奇怪的NullPointerException
。鉴于此(无用的示例性)功能:
Integer getNumber() {
return null;
}
我期望编译后以下两个代码段完全相同:
Integer number;
if (condition) {
number = getNumber();
} else {
number = 0;
}
与
Integer number = (condition) ? getNumber() : 0;
。
事实证明,如果
condition
是true
,则if
语句可以正常工作,而第二个代码段中的三元运算则抛出NullPointerException
。似乎三元操作已决定将两个选项都类型转换为int
,然后再将结果自动装箱为Integer
!?!!实际上,如果我将0
显式转换为Integer
,则该异常消失。换一种说法:Integer number = (condition) ? getNumber() : 0;
与以下内容不同:
Integer number = (condition) ? getNumber() : (Integer) 0;
。
因此,似乎三元运算符和等效的
if-else
语句之间存在字节码差异(这是我没想到的)。这就提出了三个问题:为什么会有区别?这是三元实现中的错误还是类型转换的原因?鉴于存在差异,三元运算的性能要比等效的if
语句高还是低(我知道,差异不能很大,但仍然可以)? 最佳答案
根据JLS:-
条件表达式的类型确定如下:
如果第二个和第三个操作数具有相同的类型(可能是null类型),则这是条件类型
表达。
如果第二个和第三个操作数之一是原始类型T,而另一个的类型是应用装箱转换的结果
(第5.1.7节)设为T,则条件表达式的类型为T。
关于java - NullPointerException通过Java三元运算符的自动装箱行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46178752/