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

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

问题描述

前几天我遇到了一个非常奇怪的 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;

.

结果是,如果 conditiontrueif 语句可以正常工作,而第二个代码段中的三元操作会抛出一个空指针异常.似乎三元运算决定在将结果自动装箱回 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屋!

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