不需要的 NullPointer三元运算符中的异常 - 为什么?

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

value = condition ? getDouble() : 1.0;

在早期的行中,当我使用而不是一切工作时,这很奇怪。nullgetDouble()

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);
    }
}

有人可以帮助我理解这种行为吗?


答案 1

当你写作时

value = condition ? null : 1.0;

的类型必须是引用类型,因此类型是 ,它可以保存值。condition ? null : 1.0Doublenull

当你写作时

value = condition ? getDouble() : 1.0;

并返回 ,它相当于编写:getDouble()null

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

在这种情况下,编译器将 a 和 a 视为三元条件运算符的第 2 个和第 3 个参数,并确定表达式的类型应为 。因此,它取消了 to 的框,得到 。DoubledoubledoublenulldoubleNullPointerException

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

如果第 2 和第 3 个操作数是 和 ,则条件表达式类型是 和 的最小上限,即 。nulldoubleDoublenullDouble

如果第 2 和第 3 个操作数是 和 ,则条件表达式类型为 。Doubledoubledouble


答案 2

#jls-15.25

enter image description here

如果第 2 个操作数是 ,而第 3 个操作数是 ,则结果为:Doubledouble

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

将是 .double

当你尝试将一个(返回者)转换为,将被抛出。Double nullgetDouble()doubleNPE


推荐