前几天,我因三元运算符中意外的类型转换而遇到了一个非常奇怪的NullPointerException。鉴于此(无用的示例性)功能:

Integer getNumber() {
    return null;
}


我期望编译后以下两个代码段完全相同:

Integer number;
if (condition) {
    number = getNumber();
} else {
    number = 0;
}




Integer number = (condition) ? getNumber() : 0;




事实证明,如果conditiontrue,则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/

10-16 23:30