46

我明白为什么以下是错误的:

byte a = 3; 
byte b = 8; 
byte c = a + b;  // compile error

它不会编译。表达式总是产生一个int. 所以我们应该进行显式转换:

byte c = (byte) (a + b);   // valid code

我不明白为什么以下是正确的

byte d = 3 + 8;   // it's valid! why?

因为文字整数(例如 3 或 8)总是隐含的int. 并且int-or-smaller表达式总是导致int太。谁能解释这里发生了什么?

我唯一能猜到的是编译器将此表达式等同于以下内容:

byte d = 11;

并且不认为这是一种表达方式。

4

3 回答 3

47
于 2013-06-14T14:41:49.340 回答
41

我唯一能猜到的是编译器将此表达式等同于以下内容:

是的,它确实。只要右侧表达式由常量组成(适合所需的原始类型——请参阅@Jason 的答案,了解 JLS 对此的确切说法),您就可以这样做。这将无法编译,因为 128 超出范围:

byte a = 128;

请注意,如果您像这样转换您的第一个代码片段:

final byte a = 3; 
final byte b = 8; 
byte c = a + b;

它编译!由于您的两个字节是final 并且它们的表达式是常量,这一次,编译器可以确定结果在第一次初始化时将适合一个字节。

但是,这不会编译:

final byte a = 127; // Byte.MAX_VALUE
final byte b = 1;
byte c = a + b // Nope...

编译器将出错并出现“可能的精度损失”。

于 2013-06-14T14:35:09.377 回答
1

这是因为38编译时常量。

因此,在编译发生时,编译器可以识别出3 + 8可以适合byte变量的内容。

如果您将aandb设为最终(常量)变量。a + b将成为编译时间常数。因此,它将毫无问题地编译。

    final byte a = 3;
    final byte b = 8;
    byte c = a + b;
于 2016-02-11T07:55:31.113 回答