自动拆箱需要三元if-else


23

这段代码可以正常工作:-

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

但这会引发空指针异常,而Eclipse警告需要自动拆箱:-

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

为什么会这样,请有人指导吗?

Answers:


22

三元条件表达式的类型

1 <= 3 ? nullInt : -1

int(JLS包含几个表,这些表根据第二和第三操作数的类型来描述三元条件运算符的类型)。

因此,当尝试取消nullIntinta的装箱时,将NullPointerException引发a。

为了获得if-else代码段的行为,您需要编写:

1 <= 3 ? nullInt : Integer.valueOf(-1)

现在,表达式的类型将为Integer,因此不会进行拆箱。


4
只需添加到您的答案,这里有提到表:docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

我很确定三元运算符的参数必须是同一类型。由于您使用-1并且某些常量nullint编译器会尝试将其拆箱nullint以获取价值。然后将其自动装箱以存储在secondNull变量中。


3

这是因为当条件运算符的两个操作数? :是原始类型及其装箱的引用类型时,将完成装箱转换(JLS§15.25.2):

数字条件表达式的类型确定如下:

  • ...
  • 如果第二个操作数和第三个操作数之一是原始类型T,而另一个操作数的类型是对T应用装箱转换(第5.1.7节)的结果,则条件表达式的类型为T。

通常,用表达式替换if语句? :并不总是保留代码的含义,因为? :表达式本身需要具有编译时类型。这意味着当两个操作数的类型不同时,必须对一个或两个进行转换,以使结果具有一致的编译时类型。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.