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

请考虑以下代码段:

// 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 

这种行为有什么解释吗?

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

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

Java编译器通常会隐式地接受扩展转换(例如, byteint ),因为不会丢失信息( 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可由一个byte表示,因此转换是隐含的。 如果你尝试byte b1 = 128 ,你会得到一个关于不兼容类型的错误,因为128不能用byte表示。 我们在这里允许隐式转换的唯一原因是因为我们使用的是常量表达式

    我们没有在int i5 = 100L获得隐式转换(即使100在int范围内),因为它只是在允许的隐式转换中没有列出(变量的类型, int ,不是byteshort或者char )。

    我们也没有在byte a = 0L得到隐式转换,这次是因为常量表达式是long类型,而不是byteshortcharint

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

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

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

你必须手动施放

 int i5 = (int)100L; 

因为long类型有8个字节…