赋值时奇怪的 Java 三元行为。Java在幕后做了什么来实现这一点?

Tim*_* Z. 10 java nullpointerexception conditional-operator

几天前,我遇到了一个有趣的场景,我找不到任何关于 Java 如何或为什么让以下发生的文档。(此代码段只是该错误的简化形式。)

    @Test
    public void test() {
      boolean bool = false;
      Integer intVal = Integer.valueOf(5);
      Long longVal = null;
      Long result = bool ? intVal : longVal;

      System.out.println(" > " + result);
   }
Run Code Online (Sandbox Code Playgroud)

在上面的片段中:

如果 bool = true,则您将获得值“5”;

但是如果 bool = false,那么在尝试评估三元运算时会得到一个空指针异常。不是打印语句。


为了解决这个问题,我只是将“结果”更改为

Long result = bool ? Long.valueOf(intVal) : longVal;
Run Code Online (Sandbox Code Playgroud)

这样做,将提供我需要的预期行为:

如果 bool = true,则您将获得值“5”;

但是如果 bool = false,那么你会得到 'null'


现在有趣的部分是,如果你把它拆分成一个普通的 if/else 语句,那么 java 不会让你编译

longVal = intVal; 
Run Code Online (Sandbox Code Playgroud)

但它没有通过三元运算符捕获它。那么 Java 做了什么来使它在原始代码段中成为空点?

(Java 11)

Die*_*eno 10

当你这样做时:

Long result = bool ? intVal : longVal
Run Code Online (Sandbox Code Playgroud)

此表达式返回 a long,当bool为 false 时,它​​会尝试拆箱null为 Long 值以适合result变量并抛出 NPE。

当你这样做时:

Long result = bool ? Long.valueOf(intVal) : longVal
Run Code Online (Sandbox Code Playgroud)

此表达式已返回,Long则无需拆箱,null值已成功分配给result变量。

参考:

正如评论部分所讨论的,为了更好地理解为什么会发生这种情况,请查看 JLS 的以下部分: