Java自动拳击/拆箱怪异

时间:2010-10-28 17:45:26

标签: java autoboxing

  

可能重复:
  Booleans, conditional operators and autoboxing
  Java, Google Collections Library; problem with AbstractIterator?

以下代码生成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),但为什么呢?为什么更改三元运算符中的另一个表达式(如第二个示例中)修复它?任何人都可以提供某种形式的叙述,确切地知道两个例子中的内容何时,什么以及为什么被盒装和拆箱?

1 个答案:

答案 0 :(得分:18)

来自section 15.25 of the Java Language Specification

  

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

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

所以它遵循最后一个子弹,执行二进制数字促销,执行拆箱转换。因此条件运算符表达式的类型为int,即使您将其分配给Integer。它正试图在null上执行拆箱转换,因此例外。