NullPointerException 通过 Java 三元运算符的自动装箱行为 [英] NullPointerException through auto-boxing-behavior of Java ternary operator
问题描述
前几天我遇到了一个非常奇怪的 NullPointerException
,这是由三元运算符中的意外类型转换引起的.鉴于这个(无用的示例)功能:
I tripped across a really strange NullPointerException
the other day caused by an unexpected type-cast in the ternary operator. Given this (useless exemplary) function:
Integer getNumber() {
return null;
}
我期望编译后以下两个代码段完全相同:
I was expecting the following two code segments to be exactly identical after compilation:
Integer number;
if (condition) {
number = getNumber();
} else {
number = 0;
}
对比
Integer number = (condition) ? getNumber() : 0;
.
结果是,如果 condition
是 true
,if
语句可以正常工作,而第二个代码段中的三元操作会抛出一个空指针异常
.似乎三元运算决定在将结果自动装箱回 Integer
之前将两个选项都类型转换为 int
!?!事实上,如果我显式地将 0
强制转换为 Integer
,异常就会消失.换句话说:
Turns out, if condition
is true
, the if
-statement works fine, while the ternary opration in the second code segment throws a NullPointerException
. It seems as though the ternary operation has decided to type-cast both choices to int
before auto-boxing the result back into an Integer
!?! In fact, if I explicitly cast the 0
to Integer
, the exception goes away. In other words:
Integer number = (condition) ? getNumber() : 0;
不等同于:
Integer number = (condition) ? getNumber() : (Integer) 0;
.
因此,三元运算符和等效的 if-else
语句之间似乎存在字节码差异(这是我没想到的).这就提出了三个问题:为什么会有差异?这是三元实现中的错误还是类型转换的原因?鉴于存在差异,三元运算的性能是否比等效的 if
语句更高或更低(我知道,差异不会很大,但仍然如此)?
So, it seems that there is a byte-code difference between the ternary operator and an equivalent if-else
-statement (something I didn't expect). Which raises three questions: Why is there a difference? Is this a bug in the ternary implementation or is there a reason for the type cast? Given there is a difference, is the ternary operation more or less performant than an equivalent if
-statement (I know, the difference can't be huge, but still)?
推荐答案
根据 JLS:-
条件表达式的类型确定如下:
The type of a conditional expression is determined as follows:
- 如果第二个和第三个操作数的类型相同(可能是空类型),那就是条件的类型表达.
- 如果第二个和第三个操作数之一是原始类型T,另一个的类型是应用装箱转换的结果
(§5.1.7) 到 T,则条件表达式的类型为 T.
这篇关于NullPointerException 通过 Java 三元运算符的自动装箱行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!