Java自动装箱/拆箱wierdness

Java自动装箱/拆箱wierdness,java,autoboxing,Java,Autoboxing,可能的重复项: 下面的代码生成一个NPE: Integer test = null; Integer test2 = true ? test : 0; System.out.println(test2); 要在没有异常的情况下正确打印“null”,需要以下代码: Integer test = null; Integer test2 = true ? test : (Integer)0; System.out.println(test2); 在第一个示例中,“test”很明显被取消绑定(转

可能的重复项:

下面的代码生成一个NPE:

Integer test = null;
Integer test2 = true ? test : 0;
System.out.println(test2);
要在没有异常的情况下正确打印“null”,需要以下代码:

Integer test = null;
Integer test2 = true ? test : (Integer)0;
System.out.println(test2);
在第一个示例中,“test”很明显被取消绑定(转换为原生int),但是为什么呢?为什么改变三元运算符中的另一个表达式(如第二个示例)可以解决这个问题?有人能提供一些关于这两个例子中的东西何时、何时以及为什么装箱和拆箱的叙述吗?

来源:

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

  • 如果第二个和第三个操作数具有相同的类型(可能是null类型),则这就是条件表达式的类型。
    • 如果第二个和第三个操作数中的一个为boolean类型,另一个为boolean类型,则条件表达式的类型为boolean
    • 如果第二个和第三个操作数中的一个为null类型,而另一个操作数的类型为引用类型,则条件表达式的类型为该引用类型
    • 否则,如果第二个和第三个操作数的类型可转换为数值类型(§5.1.8),则有几种情况:
      • 如果其中一个操作数的类型为byte或byte,而另一个操作数的类型为short或short,则条件表达式的类型为short
      • 如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式,其值可在T类型中表示,则条件表达式的类型为T
      • 如果其中一个操作数为Byte类型,而另一个操作数为int类型的常量表达式,其值可在Byte类型中表示,则条件表达式的类型为Byte
      • 如果其中一个操作数是Short类型,而另一个操作数是int类型的常量表达式,其值可在Short类型中表示,则条件表达式的类型为Short
      • 如果其中一个操作数的类型为;字符,另一个操作数是int类型的常量表达式,其值可在char类型中表示,则条件表达式的类型为char
      • 否则,二进制数字提升(§5.6.2)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。请注意,二进制数字提升执行拆箱转换(§5.1.8)和值集转换(§5.1.13)

所以它遵循最后一个项目符号,执行二进制数字升级,执行取消装箱转换。因此,条件运算符表达式的类型是
int
,即使您将其分配给
整数
。它试图在
null
上执行取消装箱转换,因此出现了异常。

请参阅或[Java,Google Collections Library;AbstractIterator的问题?](),这是关于
int
。仍然没有人回答(对于此特定示例)装箱和自动装箱的时间和内容顺序,由于
test
0
之间存在二进制数字提升,因此
test
未绑定。在第二种情况下,强制转换框
0