代码之家  ›  专栏  ›  技术社区  ›  GreenieMeanie

Java自动装箱/拆箱智能[复制]

  •  8
  • GreenieMeanie  · 技术社区  · 14 年前

    可能重复:
    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);
    

    要正确打印“空”而不出现异常,需要此代码:

    Integer test = null;
    Integer test2 = true ? test : (Integer)0;
    System.out.println(test2);
    

    在第一个示例中,很明显“test”正在被取消绑定(转换为本机int),但是为什么呢?为什么更改三元运算符中的另一个表达式(如第二个示例中所示)可以修复它?有人能提供一些关于什么时候,什么,为什么这两个例子中的东西被装箱和拆箱的叙述吗?

    1 回复  |  直到 14 年前
        1
  •  18
  •   Jon Skeet    14 年前

    section 15.25 of the Java Language Specification :

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

    • 如果第二个和第三个操作数具有相同的类型(可能是空类型),则这是条件表达式的类型。
      • 如果第二个和第三个操作数中的一个是Boolean类型,另一个是Boolean类型,则条件表达式的类型是Boolean。
      • 如果第二个和第三个操作数中的一个为空类型,另一个为引用类型,则条件表达式的类型为该引用类型。
      • 否则,如果第二个和第三个操作数的类型可转换为数字类型(_§5.1.8),则存在以下几种情况:
        • 如果其中一个操作数的类型为byte或byte,而另一个操作数的类型为short或short,则条件表达式的类型为short。
        • 如果其中一个操作数是t类型,其中t是byte、short或char,而另一个操作数是int类型的常量表达式,其值可在t类型中表示,则条件表达式的类型是t。
        • 如果其中一个操作数是byte类型,另一个操作数是int类型的常量表达式,其值可以用byte类型表示,则条件表达式的类型是byte。
        • 如果其中一个操作数是short类型,另一个操作数是int类型的常量表达式,其值可以用short类型表示,则条件表达式的类型是short。
        • 如果其中一个操作数是类型;character,另一个操作数是int类型的常量表达式,其值在char类型中可表示,则条件表达式的类型是char。
        • 否则,对操作数类型应用二进制数字提升(_§5.6.2),条件表达式的类型是第二个和第三个操作数的提升类型。注意,二进制数字提升执行拆箱转换(_§5.1.8)和值集转换(_§5.1.13)。

    所以它遵循最后一个要点,执行二进制数字升级,执行取消装箱转换。所以条件运算符表达式的类型是 int ,即使您将它分配给 Integer . 它正在尝试对 null 因此出现了例外。