返回类型Object的方法中的NullPointerException

Big*_*Bug 8 java nullpointerexception

为什么以下抛出NullPointerException?:

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null;
}

public static void main(String [ ] args) {
    myTest(); 
}
Run Code Online (Sandbox Code Playgroud)

我知道如果我执行以下任一操作,代码将不会抛出NullPointerException:

一个)

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : (Object) null;
}

public static void main(String [ ] args) {
    myTest(); 
}
Run Code Online (Sandbox Code Playgroud)

B)

public static Object myTest() { 
    Boolean x = false; 
    Boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null;
}

public static void main(String [ ] args) {
    myTest(); 
}
Run Code Online (Sandbox Code Playgroud)

此外,如果我完全更改代码并执行以下操作:

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 

    if(x && y) {
        return new Object(); 
    } else if(x) {
        return x; 
    } else if(y) {
        return y;
    } else {
        return null;
    }
}

public static void main(String [ ] args) {
    myTest(); 
}
Run Code Online (Sandbox Code Playgroud)

我想编译器正在进行某种优化,并以某种方式弄乱了一些东西?我假设它是某种类型的转换问题,但为什么在这种情况下会抛出NullPointerException而不是ClassCastException?任何关于为什么会发生这种情况的信息将不胜感激!

提前致谢

Aug*_*ust 6

如果为可读性添加一些括号:

return (x && y) ? (new Object()) : (x ? x : (y ? y : null));
Run Code Online (Sandbox Code Playgroud)

您可以看到,y ? y : null编译器将尝试取消装箱null(以便类型匹配),从而导致抛出NPE.

  • 完成:`y:null`的类型由`y`设置,因为左操作数为null.如果添加`(Object)null`,则设置类型,防止autounboxing为`boolean`,如果添加`Boolean y`,则不需要取消装箱,因为`null`符合`Boolean`类型. (2认同)
  • 经过测试,NPE显然发生在`(x?x:...)`,因为编译器认为`(y?y:null)`的结果必须是`boolean` (2认同)