这段 Java 代码如何编译无误?

How can this Java code compile without error?

有人可以解释为什么这个 Java 代码可以编译吗?

public class Main {
     public static void main(String []args){
        System.out.println(foo(true));
        System.out.println(foo(false));
     }

     public static boolean foo(boolean value) {
         // this should make the compiler say something, at least complain a bit...
         return value ? true : null;
     }
}

正如 Oliver 在评论中所说,编译 的原因是自动装箱。

null 可以自动装箱为 Boolean,可以自动拆箱为 boolean,让编译器满意。在运行时自动装箱工作,但是当它被拆箱到 boolean 时它会抛出 NullPointerException.

我们有什么样的条件表达式(JLS 15.25)?

  • 显然不是数值条件表达式。
  • 布尔条件表达式需要两个 boolean 类型的操作数,第三个操作数 null
  • 违反了这一点
  • 因此我们有一个 reference conditional expression

供参考条件表达式 Table 15.25-E 指定布尔值(第 2 个)和空值(第 3 个)的组合确定完整表达式的类型为 lub(Boolean,null)

对于运行时评估,这句话提供了所需的清晰度:

At run time, the first operand expression of the conditional expression is evaluated first. If necessary, unboxing conversion is performed on the result.

根据第一个操作数,会发生以下情况之一:

  • true 被自动装箱为 Boolean
  • null 已被采用,它已经与 Boolean 兼容(基于 JLS-4.1)(这不是另一个答案所声称的自动装箱)

生成的 Boolean 将被自动拆箱,在第二种情况下将抛出 NullPointerException.