Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
赋值上下文Long和int中的Java原语转换_Java - Fatal编程技术网

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

赋值上下文Long和int中的Java原语转换,java,Java,为什么Long赋值会导致编译时错误,而Byte赋值没有问题 Long ll=102导致编译器错误“类型不匹配:无法从int转换为Long”。我假设编译器会将102的范围扩大到long,然后将框扩展到long。 但事实并非如此 但是字节bb=101未生成编译器错误。在这里,我猜101被缩小到字节(非长整型常数),然后被装箱到字节。 当变窄没有问题时,加宽有什么问题?这是因为您使用的是Long而不是Long。Java自动装箱不会在同一步骤中同时从int转换为long,然后从autoboxlong转换

为什么
Long
赋值会导致编译时错误,而
Byte
赋值没有问题

Long ll=102
导致编译器错误“类型不匹配:无法从int转换为Long”。我假设编译器会将102的范围扩大到
long
,然后将框扩展到
long
。 但事实并非如此

但是
字节bb=101未生成编译器错误。在这里,我猜101被缩小到
字节
(非长整型常数),然后被装箱到
字节

当变窄没有问题时,加宽有什么问题?

这是因为您使用的是
Long
而不是
Long
。Java自动装箱不会在同一步骤中同时从
int
转换为
long
,然后从autobox
long
转换为
long

将代码更改为
long ll
,它就会工作

java中没有用于
字节
原语的标记-在
字节
(-128到+127)的有效范围内输入的任何值都可以视为
字节
整数
,具体取决于上下文。在这种情况下,它将其处理为
字节
,然后自动装箱就可以处理它了

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

  • 自动装箱也不会铸造;例如,它只会自动将
    long
    框为
    long
    ,将
    int
    框为
    整数
    ,等等
  • 在Java中,数字文本本质上是
    int
  • 因此,应该清楚为什么分配给
    Long
    不起作用:一个
    int
    试图转换为
    Long
    ,然后一步自动装箱到
    Long
    。。。不行

    但是,在正确的上下文中,
    -128
    127
    范围内的数字文字可能被解释为
    字节
    文字,因此对
    字节
    的赋值有效。

    请参见

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

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

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

    这样就好了

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

    Long long1 = (long) 102;
    Long long2 = 102L;
    Long long3 = 102l;
    
    工作,因为

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

    • 如果变量的类型是byte、short或char,并且常量表达式的值可以在变量的类型中表示,则可以使用窄化原语转换
    因此,
    101
    是一个整数文本,但是有一个赋值需要进行缩小转换(int->byte),并且
    int
    的值在
    byte
    值范围内。因此,它可以表示为变量类型(参见规范),并进行转换

    这当然不会起作用

    Byte bb = 101;
    

    顺便说一句,长ll=102L可以,谢谢。我知道更改代码以避免编译器错误,但我想了解编译器的行为。顺便说一句,如果可以使用原语,则不要使用对象/包装器,因为它们更简单、更快。此类代码用于考试准备,而不是生产代码。@PeterLawrey对象包装器在null为有效值时非常有用。我更喜欢使用它,而不是像-1这样的哨兵值。自动装箱会将其转换为整数(如规范所述),但整数不能转换为Long。那个么为什么整数可以分配给字节(字节bb=101工作正常)?不令人信服。字节bb=128;由于值超出范围而不工作。但当给定范围内的值时,缩小有效,而加宽无效。原因是什么?谢谢,我知道了。非长常量表达式将适当缩小。但永远不会变宽。@user3110711是的,就是这样。我更新了我的答案,让它更清楚。谢谢。这看起来合乎逻辑。因此,虽然装箱文本是根据目标类型解释的。谢谢。这看起来合乎逻辑。因此,虽然装箱文本是基于目标类型解释的。
     Byte bb = 128; // can not be represented as the variable type. Thus no narrowing conversion.