4

我不明白为什么 java 不进行扩展然后自动装箱。

Integer i = (short) 10;

我认为会发生以下情况:

  1. 10首先从到缩小转换short
  2. short然后会扩大到int
  3. int然后会自动装箱到Integer.

相反,这是一个编译错误。

示例 2:

短 x = 10;
整数 y = x;

这也失败了。

4

4 回答 4

6

根据JLS,第 5.2 节,处理赋值转换

赋值上下文允许使用以下之一:

  • 身份转换(§5.1.1)

  • 扩大的原始转换(§5.1.2)

  • 扩大参考转换(§5.1.5)

  • 一个装箱转换(第 5.1.7 节)可选地后跟一个扩大的参考转换

  • 一个拆箱转换(第 5.1.8 节)可选地后跟一个扩大的原始转换。

不能同时应用两个转换(加宽原始转换和装箱转换);此处只能应用一次转换,因此必须导致错误。

解决方案是将shortback 转换为int(转换转换),这将允许赋值转换成为装箱转换:

Integer i = (int) (short) 10;

(或者在这里,首先不要将其投射到short。)

Integer i = 10;
于 2013-07-29T23:32:32.867 回答
3

这里发生的是从intto的强制转换short,然后是从shortto的尝试赋值转换Integer

赋值转换(第 5.2 节)允许先装箱然后加宽,但不允许先加宽然后装箱。

赋值上下文允许使用以下之一:

  • 身份转换(§5.1.1)

  • 扩大的原始转换(§5.1.2)

  • 扩大参考转换(§5.1.5)

  • 一个装箱转换(第 5.1.7 节)可选地后跟一个扩大的参考转换

  • 一个拆箱转换(第 5.1.8 节)可选地后跟一个扩大的原始转换。

于 2013-07-29T23:32:21.457 回答
0

在 java 中,无论您是否这样做,它都遵循“自动装箱然后加宽”的顺序: int x =5; 对象 obj = x;

或这个:

诠释 x = 5; 长 l = x;

只有当存在一种关系时才会发生扩大。
因此,虽然应用上述序列第一种情况对编译器非常有效,因为 int 将自动装箱为 Integer,然后分配给 Object,即扩大(即先自动装箱然后扩大),处于 Is-A 关系。但是在第二种情况下,如果 int x 是对 Integer 的 autbox 并且对 Long 的分配是不允许的,则不是 is-a 关系,因此会引发编译错误。

于 2013-12-27T07:04:41.217 回答
0

可以使用关于自动装箱和扩展的重载来模拟类似的用例。

public static void m(short s) {
    System.out.println("widening");
  }

public static void m(Integer i) {
    System.out.println("Autoboxing");
}

public static void main(String[] args) {
    short x = 10;
    m(x);
}

输出:加宽

因此,简而言之,我们可以说,在 Java 中,Widening 支配着 Autoboxing

于 2020-02-02T09:58:03.340 回答