为什么这个链式条件运算符会抛出 NPE?

Why does this chained conditional operator throw NPE?

Boolean isTrue = condition1 ? true : (
                                id == null ? null : condition2);

当condition1 returns 为真时,代码运行正常(有道理),但当condition1 为假时,代码失败并出现空指针异常。 自己试试 - https://www.ideone.com/epj9Jd

这有点令人困惑,没有意义。对此的解释将不胜感激。

Boolean isTrue = condition1 ? true : (
                            id == null ? null /* <- HERE*/ : condition2);

好的,所以这有点粗糙。问题是由于在标记为 HERE 的点引入的 null 值被取消装箱。

为什么?

因为condition1 ? true : ...的类型是第2个操作数的类型;即 boolean。因此 Boolean 的子表达式 id == null ? null : condition2 必须拆箱为 boolean.

但是拆箱 null 会给你一个 NPE。


Interesting. I would have expected better type inference here.

不幸的是,当自动装箱/拆箱被添加到语言中时,涉及装箱类型的条件表达式的类型规则在 Java5 中得到了巩固。那是在 Java 获得对类型推断的重要支持之前 15(?)年。

规则一旦固化,就无法更改……不破坏向后兼容性。

(但实际上这不是类型推断问题。打字没问题。这里真正的问题是对此有两种可能的语义,一种涉及拆箱 null,另一种不涉及' t. 键入条件的 JLS 规则意味着在这种情况下使用第一个。)