这个Java代码如何编译而不出错?

这个Java代码如何编译而不出错?,java,compiler-errors,compilation,javac,Java,Compiler Errors,Compilation,Javac,有人能解释一下为什么这个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 mak

有人能解释一下为什么这个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
可以自动装箱到一个
布尔值
,该布尔值可以自动取消绑定到一个
布尔值
,使编译器感到高兴。在运行时,自动装箱可以工作,但是当它被取消绑定到一个
布尔值时,它将抛出一个
NullPointerException

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

  • 显然不是数字条件表达式
  • 布尔条件表达式需要两个类型为
    boolean
    的操作数,第三个操作数为
    null
  • 因此,我们有一个
参考条件表达式表指定布尔值(第二个)和null值(第三个)的组合确定完整表达式的类型为
lub(布尔值,null)

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

在运行时,首先计算条件表达式的第一个操作数表达式。如有必要,将对结果执行取消装箱转换

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

  • true
    自动装箱到
    Boolean
    ,或
  • 采用
    null
    ,该值已与
    布尔值兼容(基于)(这不是另一个答案所声称的自动装箱)

生成的
Boolean
将自动取消绑定,在第二种情况下,将抛出
NullPointerException

自动装箱…..您查看了JLS吗?你认为这违反了哪条规则?这看起来像是@OliverCharlesworth所涵盖的,但为什么它在顺序颠倒时不编译?@milin-但它确实编译:/@JonSkeet我找不到任何关于第二个操作数为“布尔”而第三个操作数为“空”的规则,但我不确定这是否构成“没有规则被破坏”,相反,我有一种感觉,它被忽略了……但为什么它在顺序颠倒时不编译呢?哪个顺序?正如上面OliverCharlesworth提到的,我错了——它确实编译了!呸。我不想开始挖掘关于三元运算符自动装箱或其他一些模糊规则:)谢谢你的努力!:)我现在了解到,整个表达式的返回类型是从操作数派生的,然后根据应该保存求值表达式的类型进行验证。我无法摆脱这种失败的感觉,但我明白为什么它不会。。。