为什么这个链式条件运算符会抛出 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 规则意味着在这种情况下使用第一个。)
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 规则意味着在这种情况下使用第一个。)