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

Lal*_*ith 19 java

Long ll = 102; // Error
Byte bb = 101; // No error
Run Code Online (Sandbox Code Playgroud)

为什么在Long赋值正常的情况下赋值会导致编译时错误Byte

Long ll = 102导致编译器错误"类型不匹配:无法从int转换为Long".我假设编译器将加宽102到long然后框到Long.但它没有发生.

但是Byte bb = 101;不会产生编译器错误.在这里我猜,101缩小为byte(非长积分常数),然后装箱Byte.当缩小没有问题时,扩大的问题是什么?

Tim*_*m B 12

发生这种情况是因为你使用Long而不是long.Java的自动装箱不会无论从转换intlong,然后autobox longLong在相同的步骤.

将代码更改为long ll,它将起作用.

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

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


Ren*_*ink 10

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;
Run Code Online (Sandbox Code Playgroud)

第二个

Byte bb = 101;
Run Code Online (Sandbox Code Playgroud)

工作,因为5.2.作业转换

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

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

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

这当然不行

 Byte bb = 128; // can not be represented as the variable type. Thus no narrowing conversion.
Run Code Online (Sandbox Code Playgroud)


Boh*_*ian 6

  1. 自动装箱不投; 例如,它才会自动箱一longLong,一intInteger
  2. 在Java中,数字文字本质上是 int

因此,应该清楚为什么赋值Long将不起作用:a int试图将其转换为一个单独的long自动盒装Long...不用了.

然而,在范围数字文本-128127可以被解释为byte在正确的上下文文字,所以这就是为什么分配给Byte作品.