赋值上下文中的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 long
为Long
。
将您的代码更改为long ll
,它将起作用。
java中没有用于byte
基元的标记 – 在byte
(-128到+127)的有效范围内输入的任何值都可以视为byte
或integer
具体取决于上下文。 在这种情况下,它将其作为byte
处理,然后自动装箱能够对其进行处理。
我不确定为什么决定让Java以这种方式工作。 似乎字节处理与所有其他数字类型不一致。
- 自动拳击也不投; 例如,它只会自动将
long
设置为Long
,将int
设置为Integer
等。 - 在Java中,数字文字本身就是
int
所以,应该清楚为什么对Long
的赋值不起作用:一个int
试图被强制转换为long
然后自动盒装到Long
一步……不行。
但是, -128
到127
范围内的数字文字可能会在正确的上下文中被解释为byte
文字,因此这就是Byte
的赋值工作原因。