[英]Java: Widening and autoboxing conversion issue
我不明白为什么 java 不进行扩展然后自动装箱。
Integer i = (short) 10;
我认为会发生以下情况:
10
缩小到short
。short
然后会扩大到int
。int
然后会自动装箱到Integer
。相反,它是一个编译错误。
示例 2:
短 x = 10;
整数 y = x;
这也失败了。
根据JLS 第 5.2 节,处理赋值转换:
赋值上下文允许使用以下之一:
身份转换(第 5.1.1 节)
扩大原始转换(第 5.1.2 节)
扩大参考转换(第 5.1.5 节)
装箱转换(第 5.1.7 节)可选地后跟扩展参考转换
一个拆箱转换(第 5.1.8 节),可选地跟随一个扩展原始转换。
不能同时应用两次转换(扩展原语转换和装箱转换); 这里只能应用一种转换,因此它必须导致错误。
解决方案是将short
转换回int
(转换转换),这将允许分配转换为装箱转换:
Integer i = (int) (short) 10;
(或者在这里,首先不要将其short
。)
Integer i = 10;
这里发生的是从int
到short
的强制转换,然后尝试从short
到Integer
赋值转换。
赋值转换(第5.2 节)允许先装箱然后加宽,但不能加宽然后装箱。
赋值上下文允许使用以下之一:
身份转换(第 5.1.1 节)
扩大原始转换(第 5.1.2 节)
扩大参考转换(第 5.1.5 节)
装箱转换(第 5.1.7 节)可选地后跟扩展参考转换
一个拆箱转换(第 5.1.8 节),可选地跟随一个扩展原始转换。
在 java 中,它遵循“自动装箱然后加宽”的顺序,无论您是否这样做: int x =5; 对象 obj = x;
或这个:
整数 x = 5; 长 l = x;
只有当存在 is-a 关系时才会发生加宽。
因此,虽然应用上述序列第一种情况对编译器非常有效,因为 int 将自动装箱为 Integer 然后分配给 Object,即加宽(即先自动装箱然后加宽),处于 Is-A 关系。 但是在第二种情况下,如果 int x 是 Integer 的 autbox 并且分配给 Long 则不允许,因为不是 is-a 关系,因此会引发编译错误。
可以使用关于自动装箱和加宽的重载来模拟类似的用例。
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 中主导了自动装箱
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.