为什么允许从int到byte而不是从long到int的隐式缩小转换?

sim*_*Dev 3 java

请考虑以下代码段:

// automatic casting works for int to byte conversion as integer literal 127
// is in the range for byte
byte b1 = 127; //OK

// automatic casting doesn't work for long to int conversion 
// even if long literal is in the range of int.
int i5 = 100L; // NOT OK - compilation error
Run Code Online (Sandbox Code Playgroud)

这种行为有什么解释吗?

为什么在int到byte的情况下不需要显式转换,但需要long to int?

如何转换的Java诠释成字节?问题不同.当int值超出范围时,它是关于int到byte的隐式转换的问题.

hne*_*atl 11

byte扩展转换(例如to int)通常由Java编译器隐式接受,因为不会丢失信息(范围int大于byte).

缩小转换(例如longint,在你的情况下)可能会导致信息丢失,所以一般都要求被明确地铸造.

看到这个类似的问题,这个.Java语言规范的相关部分:

当表达式的值被赋值(第15.26节)给变量时,就会发生赋值转换:必须将表达式的类型转换为变量的类型.

...

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

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

  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:

    • 字节和常量表达式的值可在类型字节中表示

    • Short和常量表达式的值可以在short类型中表示.

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

(强调我的)


一些混淆源于我们正在处理常量表达式这一事实,因为我们正在使用数字文字.以上规范也需要仔细阅读.

要清除一些内容并直接回答一些OP的查询:

  1. 为什么一种缩小而不是另一种缩小支持隐式缩小?

    IE浏览器.为什么byte b1 = 127隐含地工作,而int i5 = 100L不是?

    byte b1 = 127执行隐式转换(参见上面引用中的粗体文本),"常量表达式的值可在类型字节中表示".也就是说,127可由a表示byte,因此转换是隐含的.如果您尝试byte b1 = 128,您将收到有关不兼容类型的错误,因为128无法表示byte.我们这里不允许隐式转换的唯一原因是因为我们使用一个常量表达式.

    我们没有得到一个隐式转换int i5 = 100L(即使100在范围内int),作为这根本就不是在允许的隐式转换上市(变量的类型,int是不是一个byte,shortchar).

    我们也不会在得到一个隐式转换byte a = 0L为常量表达式类型的,这个时候long不是类型byte,short,char,或int.

  1. 普通程序员将如何知道隐式允许哪种缩小转换?

    只有在为变量分配常量表达式时,才会发生隐式缩小转换.在这些情况下,隐式转换很好,因为我们不想一直编写代码byte b = (byte)0.与此同时,如果我们写出类似的东西,我们确实希望得到警告byte b = 128,因为它没有直观的行为.

    当我们没有分配常量表达式(例如.int x = 0; byte b = x;)时,我们总是希望在我们进行潜在有损转换时收到警告,因为它们很危险 - 因此在这种情况下显式转换也是有意义的.