赋值上下文中的Java原始转换Long和int

Long ll = 102; // Error Byte bb = 101; // No error 

为什么Long分配导致编译时错误而Byte分配正常?

Long ll = 102导致编译器错误“类型不匹配:无法从int转换为Long”。 我假设编译器会将102扩展为long ,然后将box扩展为Long 。 但它没有发生。

Byte bb = 101; 没有生成编译器错误。 在这里我猜,101缩小为byte (非长整数常量),然后Boxed to Byte 。 当缩小没有问题时,扩大的问题是什么?

见5.1.7 JLS的拳击转换

  • 如果p是int类型的值,那么装箱转换将p转换为类的引用r并输入Integer,这样r.intValue()== p

因为102是一个整数文字,它的类型是int ,自动装箱会将它转换为Integer (如规范所述),但是Integer不能转换为Long

因此,当您使用long文字或将int文字转换为long ,JLS将使用装箱转换,结果将是Long对象。

这没关系

 Long long1 = (long) 102; Long long2 = 102L; Long long3 = 102l; 

第二个

 Byte bb = 101; 

工作,因为5.2。 作业转换

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

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

所以101是一个整数文字,但是有一个需要缩小转换(int – > byte)的赋值, int的值在byte值范围内。 因此它可以表示为变量类型(参见规范)并进行转换。

当然这不会起作用

  Byte bb = 128; // can not be represented as the variable type. Thus no narrowing conversion. 

发生这种情况是因为您使用的是Long而不是long 。 Java自动装箱不会同时从int转换为long ,然后将autobox longLong

将您的代码更改为long ll ,它将起作用。

java中没有用于byte基元的标记 – 在byte (-128到+127)的有效范围内输入的任何值都可以视为byteinteger具体取决于上下文。 在这种情况下,它将其作为byte处理,然后自动装箱能够对其进行处理。

我不确定为什么决定让Java以这种方式工作。 似乎字节处理与所有其他数字类型不一致。

  1. 自动拳击也不投; 例如,它只会自动将long设置为Long ,将int设置为Integer等。
  2. 在Java中,数字文字本身就是int

所以,应该清楚为什么对Long的赋值不起作用:一个int试图被强制转换为long然后自动盒装到Long一步……不行。

但是, -128127范围内的数字文字可能会在正确的上下文中被解释为byte文字,因此这就是Byte的赋值工作原因。