Java允许将字节分配给java.lang.Short,但不允许分配给java.lang.Integer

时间:2014-08-13 17:27:22

标签: java type-conversion wrapper autoboxing

final byte b = 12;  
Short s = b;  
Integer i = b;

程序编译为Short,但是对于Integer编译失败,使用"不兼容的类型"信息。

我很难理解这种行为。我找不到任何针对这种特定情况的东西..

1 个答案:

答案 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,还要分配给FloatLongDouble也是一个错误。

有趣的是,如果b的原始声明不是final,那么分配给CharactercharShort也会失败。

Section 5.2 of the JLS对转让背景及其允许的转换主题略有说明。

  

分配上下文允许使用以下之一:

     
      
  • 身份转换(第5.1.1节)

  •   
  • 扩大原始转换(第5.1.2节)

  •   
  • 扩大参考转换(第5.1.5节)

  •   
  • 拳击转换(§5.1.7),可选地后跟扩展参考转换

  •   
  • 一个拆箱转换(第5.1.8节),可选地后跟一个加宽的原语转换。

  •   

这涵盖了所有转换为更宽的原始变量,这些变量始终是允许的,无论bfinal还是b。 (除非char为否定,否则保留,在这种情况下,对无符号Character(或b)的分配将失败。)继续:

  

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

     
      
  • 如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。

  •   
  • 如果变量的类型为:

    ,则可以使用缩小的基元转换,然后进行装箱转换。      
        
    • 字节和常量表达式的值可以在类型字节中表示。

    •   
    • 简短,常量表达式的值可以在短类型中表示。

    •   
    • 字符和常量表达式的值可以在char类型中表示。

    •   
  •   

由于finalb,因此表达式int常量表达式,允许它从12常量表达式{缩小{ {1}}到bytecharshort,然后装箱到ByteCharacterShort,但奇怪的是,不是至Integer或任何“以上”。我能想到的唯一可能的解释是,不能明确允许将原始缩小转换的常量表达式转换为IntegerLongFloat或{{ 1}}。

如果Double不是b,则不允许缩小后跟拳击,并且无法将final的非常量表达式提升为{{1}或者。