三元运算符中不需要的 NullPointerException - 为什么?

Unwanted NullPointerException in ternary operator - Why?

在执行以下代码时,我在第 NullPointerException 行得到一个 NullPointerException

value = condition ? getDouble() : 1.0;

在前面几行中,当我使用 null 而不是 getDouble() 时一切正常,这很奇怪。

public class Test {
    static Double getDouble() {
        return null;
    }

    public static void main(String[] args) {
        boolean condition = true;
        Double value;

        value = condition ? null : 1.0;         //works fine
        System.out.println(value);              //prints null

        value = condition ? getDouble() : 1.0;  //throws NPE
        System.out.println(value);
    }
}

谁能帮我理解这种行为?

写的时候

value = condition ? null : 1.0;

condition ? null : 1.0的类型必须是引用类型,所以类型是Double,可以容纳值null.

写的时候

value = condition ? getDouble() : 1.0;

getDouble()returnsnull,相当于写成:

value = condition ? ((Double) null) : 1.0;

在这种情况下,编译器将 Doubledouble 视为三元条件运算符的第二个和第三个参数,并决定表达式的类型应为 double .因此它将 null 拆箱为 double,得到 NullPointerException.

条件三元运算符的类型由JLS 15.25中的一些表决定。

如果第二个和第三个操作数是nulldouble,则条件表达式类型是Doublenull的最小上界,即Double.

如果第二个和第三个操作数为Doubledouble,则条件表达式类型为double.

#jls-15.25:

如果第二个操作数是Double,而第三个操作数是double,结果:

getCount() == 1 ? getDouble() : 1.0

将是 double

并且当您尝试将 Double null(由 getDouble() 返回)转换为 double 时,将抛出 NPE