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