三元运算符中不需要的 NullPointerException - 为啥? [复制]

Posted

技术标签:

【中文标题】三元运算符中不需要的 NullPointerException - 为啥? [复制]【英文标题】:Unwanted NullPointerException in ternary operator - Why? [duplicate]三元运算符中不需要的 NullPointerException - 为什么? [复制] 【发布时间】:2019-02-08 08:42:48 【问题描述】:

在执行以下代码时,我在行收到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);
    

谁能帮我理解这种行为?

【问题讨论】:

“将 getDouble() 更改为 null”是什么意思?该方法已在您发布的代码中返回 null。 这很奇怪...如果我更改为 null 一切正常。虽然方法返回 null 当我说更改为 null 意味着......而不是调用返回 null 的方法时,我直接使用了 null 可能相关:Tricky ternary operator in Java - autoboxing 我试图简化并同时澄清您的示例。如果我误解了您的意图,请随时回滚我的编辑。 【参考方案1】:

当你写作时

value = condition ? null : 1.0;

condition ? null : 1.0的类型必须是引用类型,所以类型为Double,可以持有值null

当你写作时

value = condition ? getDouble() : 1.0;

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

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

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

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

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

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

【讨论】:

很奇怪。我会为此提出某种票证。即使语言标准说编译器应该选择double,这是一个缩小转换,因为double 不支持null。如果我没记错的话,所有其他隐式缩小转换都像瘟疫一样被避免。我应该认为应该改变它以保持一致性。 根据上面的答案...您可以将其更改为以下内容,它将正常工作value = condition ? getDouble() : new Double(1.0); 为什么会有人知道?【参考方案2】:

见#jls-15.25:

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

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

将是double

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

【讨论】:

在 JLS 上更进一步:15.25.2 说:“如果第二个和第三个操作数之一是原始类型 T,而另一个的类型是对 @ 应用装箱转换的结果987654333@,则条件表达式的类型为T。"拳击因 NPE 失败。

以上是关于三元运算符中不需要的 NullPointerException - 为啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

堆叠三元运算符在 Angularjs 表达式中不起作用

json对象上的多属性检查三元运算符在nodejs中不起作用,而它在google chrome控制台中工作

使用三元运算符的条件渲染和 onClick 事件

多个三元运算符

三元运算符判断

select2代码的三元运算符需要说明