三元if-else的自动拆箱需求

Auto-unboxing need of ternary if-else

这段代码工作正常:-

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

为什么会这样,请大神指导一下?

三元条件表达式的类型

1 <= 3 ? nullInt : -1

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

因此,当它尝试将 nullInt 拆箱为 int 时,会抛出 NullPointerException

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

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

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

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

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

The type of a numeric conditional expression is determined as follows:

  • ...
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

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

这个有效(在 Java 1.8 中):

Integer secondNull = 1 <= 3 ? null : -1;