NullPointerException通过Java三元运算符的自动装箱行为 [英] NullPointerException through auto-boxing-behavior of Java ternary operator

查看:370
本文介绍了NullPointerException通过Java三元运算符的自动装箱行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于三元运算符中的意外类型转换,我在前一天遇到了一个非常奇怪的 NullPointerException 。鉴于此(无用的示例)函数:

 整数getNumber(){
返回null;
}

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

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

vs。

 整数=(条件)? getNumber():0; 



原来,如果条件 true 如果 -statement工作正常,第二个代码段中的三元操作会抛出 NullPointerException 。似乎三元操作决定在将结果自动装回到 Integer int 。 $ C>!?!实际上,如果我明确地将 0 转换为 Integer ,则异常就会消失。换句话说:

 整数=(条件)? getNumber():0; 

与以下内容不同:

 整数=(条件)? getNumber():(整数)0; 



所以,似乎三元运算符和等价的 if-else -statement(我没想到的)之间存在字节码差异。这提出了三个问题:为什么会有差异?这是三元实现中的错误还是有类型转换的原因?鉴于存在差异,三元运算的性能是否等同于,如果 -statement(我知道,差异不是很大,但仍然存在)?<根据 JLS : -


a的类型条件表达式确定如下:




  • 如果第二个和第三个操作数具有相同的类型(可能是null类型),那么是条件
    表达式的类型。

  • 如果第二个和第三个操作数之一是原始类型T,而另一个的类型是应用装箱转换的结果

    (§5.1.7)到T,然后条件表达式的类型是T.



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;
}

vs.

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

.

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;

is not the same as:

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

.

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)?

解决方案

According to JLS: -

The type of a conditional expression is determined as follows:

  • If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion
    (§5.1.7) to T, then the type of the conditional expression is T.

这篇关于NullPointerException通过Java三元运算符的自动装箱行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆