【问题标题】:Why does this chained conditional operator throw NPE?为什么这个链式条件运算符会抛出 NPE?
【发布时间】:2020-12-03 05:56:09
【问题描述】:
Boolean isTrue = condition1 ? true : (
                                id == null ? null : condition2);

当 condition1 返回 true 时,代码运行良好(有意义),但是当 condition1 为 false 时,代码失败并出现空指针异常。 自己试试 - https://www.ideone.com/epj9Jd

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

【问题讨论】:

  • 请出示实际完整代码。
  • 简而言之,因为id == null ? >> null <<。请改用falseBoolean.FALSE
  • 或者,更好的是minimal reproducible example
  • 确实如此。但是,然后您将其拆箱。拆箱 null 会引发 NPE。
  • 理解的诀窍在于条件表达式的类型是由第二个操作数而不是第三个操作数决定的。但真正的诀窍是避免使用null 作为Boolean ...'因为它会产生问题。

标签: java nullpointerexception runtime-error conditional-operator


【解决方案1】:
Boolean isTrue = condition1 ? true : (
                            id == null ? null /* <- HERE*/ : condition2);

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

为什么?

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

但拆箱 null 会给你一个 NPE。


有趣。我本来希望这里有更好的类型推断。

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

一旦规则被固化,它们就不能被改变......不破坏向后兼容性。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-05
    • 2011-10-10
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    相关资源
    最近更新 更多