Java自动装箱/拆箱怪异

发布于 2024-09-29 19:08:22 字数 749 浏览 3 评论 0原文

可能的重复:
布尔值、条件运算符和自动装箱
Java,Google 集合库; 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),但是为什么?为什么更改三元运算符中的其他表达式(如第二个示例中)可以修复它?谁能提供某种叙述,说明这两个示例中的内容何时、什么以及为何被装箱和拆箱?

Possible Duplicates:
Booleans, conditional operators and autoboxing
Java, Google Collections Library; problem with AbstractIterator?

The code below produces a NPE:

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

To correctly print out "null" without an exception requires this code:

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

It's obvious in the first example that "test" is being unboxed (converted to native int), but why? And why does changing the other expression in the ternary operator (as in the 2nd example) fix it? Can anyone provide some kind of narrative of exactly when, what, and why stuff in both of the examples gets boxed and unboxed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟若柳尘 2024-10-06 19:08:22

来自Java 语言规范的第 15.25 节

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

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

因此,它遵循最后一个要点,执行二进制数字提升,从而执行拆箱转换。因此,条件运算符表达式的类型为 int,即使您将其分配给 Integer 也是如此。它尝试对 null 执行拆箱转换,因此出现异常。

From section 15.25 of the Java Language Specification:

The type of a conditional expression is determined as follows:

  • If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
    • If one of the second and third operands is of type boolean and the type of the other is of type Boolean, then the type of the conditional expression is boolean.
    • If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
    • Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
      • If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
      • If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T.
      • If one of the operands is of type Byte and the other operand is a constant expression of type int whose value is representable in type byte, then the type of the conditional expression is byte.
      • If one of the operands is of type Short and the other operand is a constant expression of type int whose value is representable in type short, then the type of the conditional expression is short.
      • If one of the operands is of type; Character and the other operand is a constant expression of type int whose value is representable in type char, then the type of the conditional expression is char.
      • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

So it's following the final bullet, performing binary numeric promotion, which performs an unboxing conversion. So the type of the conditional operator expression is int, even though you're assigning it to an Integer. It's trying to perform the unboxing conversion on null, hence the exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文