只是想了解自动装箱,我除了做一件事之外:
Short s = 250;
Long l = 250;
分配Long l
失败。我预计,这是因为您无法扩大然后框(即,它试图将int
值扩大250
到 along
然后将其装箱,这是它无法做到的)。
但是,分配Short s
工作。这是怎么回事?我的假设是它仍在进行拳击和某种转换。但是,如果它知道250
适合 a的情况short
,为什么它不知道250
适合 along
呢?
只是想了解自动装箱,我除了做一件事之外:
Short s = 250;
Long l = 250;
分配Long l
失败。我预计,这是因为您无法扩大然后框(即,它试图将int
值扩大250
到 along
然后将其装箱,这是它无法做到的)。
但是,分配Short s
工作。这是怎么回事?我的假设是它仍在进行拳击和某种转换。但是,如果它知道250
适合 a的情况short
,为什么它不知道250
适合 along
呢?
通常,您不能在赋值中应用多个(隐式)转换(JLS §5.2 赋值转换):
当将表达式的值(第 15.26 节)分配给变量时,就会发生赋值转换:必须将表达式的类型转换为变量的类型。分配上下文允许使用以下之一:
- 身份转换(§5.1.1)
- 扩大的原始转换(§5.1.2)
- 扩大参考转换(§5.1.5)
- 一个装箱转换(第 5.1.7 节)可选地后跟一个扩大的参考转换
- 一个拆箱转换(第 5.1.8 节)可选地后跟一个扩大的原始转换。
Long l=250;
需要两次转换(扩大原始转换,然后是装箱转换),这就是它无法编译的原因。
Long l=250l;
编译,因为它需要一次装箱转换。
但是缩小常量表达式的转换是一种特殊情况,这就是Short s=250;
编译的原因:
此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(第 15.28 节):
- 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用窄化原语转换。
- 如果变量的类型是:
- 字节和常量表达式的值可以用字节类型表示。
- Short 并且常量表达式的值可以用 short 类型表示。
- 字符和常量表达式的值可以用 char 类型表示。
理想情况下,不应允许自动缩小。
但是由于没有字节/短文字,我们不能写
byte b = 0b;
这似乎很愚蠢
byte b = (byte)0;
所以常量整数的自动变窄是允许的,所以我们可以写
byte b = 0;
它被转移到自动装箱案例中。
对于 long/Long,因为有 long 字面量,所以这不是什么问题。尽管如此,它还是应该被允许的,因为有符号整数的自动扩展总是安全的。