三元表达式中带有自动装箱的 NullPointerException
运行以下Java代码:
boolean b = false;
Double d1 = 0d;
Double d2 = null;
Double d = b ? d1.doubleValue() : d2;
为什么会出现NullPointerException?
Run the following Java code:
boolean b = false;
Double d1 = 0d;
Double d2 = null;
Double d = b ? d1.doubleValue() : d2;
Why is there a NullPointerException?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
条件表达式
b ? 的返回类型d1.doubleValue : d2
是double
。条件表达式必须具有单一返回类型。遵循二进制数字提升的规则,d2
会自动拆箱为double
,这会在d2 == null
时导致NullPointerException
代码>.根据语言规范第 §15.25 节:
The return type of the conditional expression
b ? d1.doubleValue : d2
isdouble
. A conditional expression must have a single return type. Following the rules for binary numeric promotion,d2
is autounboxed to adouble
, which causes aNullPointerException
whend2 == null
.From the language spec, section §15.25:
因为
:
周围的两个表达式必须返回相同的类型。这意味着 Java 尝试将表达式d2
转换为double
。这意味着字节码在d2
上调用doubleValue()
-> NPE。Because the two expressions around
:
must return the same type. This means Java tries to convert the expressiond2
todouble
. This means the bytecode callsdoubleValue()
ond2
-> NPE.通常应该避免混合类型计算;将其与
?:
条件/三元复合只会使情况变得更糟。以下引用自 Java Puzzlers,《Puzzle 8:Dos Equis》:
这里应用了第3点,结果就是拆箱。当您取消装箱
null
时,自然会抛出NullPointerException
。这是混合类型计算和
?:
的另一个示例,这可能会令人惊讶:混合类型计算是至少 3 个 Java Puzzlers 的主题。
最后,这是 Java Puzzlers 的规定:
关于首选基本类型胜过装箱基元
以下引用来自《Effective Java 第二版》第 49 条:首选基本类型胜过装箱基元:
在某些地方,您别无选择,只能使用装箱基元,例如泛型,但除此之外,您应该认真考虑使用装箱基元的决定是否合理。
相关问题
You should generally avoid mixed type computation; compounding this with
?:
conditional/ternary only makes it worse.Here's a quote from Java Puzzlers, Puzzle 8: Dos Equis:
Point 3 is applied here, and it resulted in unboxing. When you unbox
null
, naturally aNullPointerException
is thrown.Here's another example of mixed-type computation and
?:
that may be surprising:Mixed-type computation is the subject of at least 3 Java Puzzlers.
In closing, here's what Java Puzzlers prescribes:
On prefering primitive types to boxed primitives
Here's a quote from Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives:
There are places where you have no choice but to use boxed primitives, e.g. generics, but otherwise you should seriously consider if a decision to use boxed primitives is justified.
Related questions
对于如下所示的两种条件返回相同的类型,您将得到结果。
Return same type for both condition like below and you will get result.