final byte b = 12;
Short s = b;
Integer i = b;
程序编译为Short,但是对于Integer编译失败,使用"不兼容的类型"信息。
我很难理解这种行为。我找不到任何针对这种特定情况的东西..
答案 0 :(得分:6)
我试图用更广泛的分配上下文组复制它:
final byte b = 12;
Byte b2 = b;
Character c = b; // Only an error if b isn't final
char c2 = b; // Only an error if b isn't final
Short s = b; // Only an error if b isn't final
short s2 = b;
Integer i = b; // Error, as indicated in the question
int i2 = b;
Long l = b; // Also an error
long l2 = b;
Float f = b; // Also an error
float f2 = b;
Double d = b; // Also an error
double d2 = b;
不仅要分配给Integer
,还要分配给Float
,Long
或Double
也是一个错误。
有趣的是,如果b
的原始声明不是final
,那么分配给Character
,char
或Short
也会失败。
Section 5.2 of the JLS对转让背景及其允许的转换主题略有说明。
分配上下文允许使用以下之一:
身份转换(第5.1.1节)
扩大原始转换(第5.1.2节)
扩大参考转换(第5.1.5节)
拳击转换(§5.1.7),可选地后跟扩展参考转换
一个拆箱转换(第5.1.8节),可选地后跟一个加宽的原语转换。
这涵盖了所有转换为更宽的原始变量,这些变量始终是允许的,无论b
是final
还是b
。 (除非char
为否定,否则保留,在这种情况下,对无符号Character
(或b
)的分配将失败。)继续:
此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):
如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。
如果变量的类型为:
,则可以使用缩小的基元转换,然后进行装箱转换。
字节和常量表达式的值可以在类型字节中表示。
简短,常量表达式的值可以在短类型中表示。
字符和常量表达式的值可以在char类型中表示。
由于final
是b
,因此表达式int
是常量表达式,允许它从12
常量表达式{缩小{ {1}}到byte
,char
或short
,然后装箱到Byte
,Character
或Short
,但奇怪的是,不是至Integer
或任何“以上”。我能想到的唯一可能的解释是,不能明确允许将原始缩小转换的常量表达式转换为Integer
,Long
,Float
或{{ 1}}。
如果Double
不是b
,则不允许缩小后跟拳击,并且无法将final
的非常量表达式提升为{{1}或者。