我理解为什么以下是错误的:
byte a = 3;
byte b = 8;
byte c = a + b; // compile error
Run Code Online (Sandbox Code Playgroud)
它不会编译.表达式总是导致int.所以我们应该做了明确的演员:
byte c = (byte) (a + b); // valid code
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么以下是正确的:
byte d = 3 + 8; // it's valid! why?
Run Code Online (Sandbox Code Playgroud)
因为字面整数(例如3或8)总是隐式的int.并且int-or-smaller表达式也总是导致int.谁能解释一下这里发生了什么?
我唯一可以猜到的是编译器将此表达式等同于以下内容:
byte d = 11;
Run Code Online (Sandbox Code Playgroud)
并不认为这是一个表达.
jas*_*son 46
这有少†做与否3 + 8进行评估,以11在编译时间,更要与事实的编译器是明确允许隐式窄ints到byteS IN某些情况下.特别是,语言规范明确允许隐式缩小转换为可以适合编译时byte的类型的常量表达式.intbyte
此外,如果表达式类型的常量表达式(§15.28) ,
byte,short,char或int:
- 如果变量的类型是
byte,,short或者char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示.常量的编译时缩小意味着
byte theAnswer = 42;允许代码如: .如果没有缩小,整数文字42具有类型的事实int将意味着需要强制转换byte:
†:显然,根据规范,需要对常量表达式进行求值,以确定它是否适合较窄的类型.但重点是,如果没有规范的这一部分,编译器将不允许进行隐式缩小转换.
我们在这里说清楚:
byte a = 3;
byte b = 8;
Run Code Online (Sandbox Code Playgroud)
允许这些的原因是由于规范的上述部分.也就是说,允许编译器将文字的隐式缩小转换3为a byte.这不是因为编译器在编译时将常量表达式计算3为其值3.
fge*_*fge 41
我唯一可以猜到的是编译器将此表达式等同于以下内容:
是的,它确实.只要右侧表达式由常量组成(符合所需的基本类型 - 请参阅@Jason对JLS所说的内容的答案),您就可以做到这一点.这将无法编译,因为128超出范围:
byte a = 128;
Run Code Online (Sandbox Code Playgroud)
请注意,如果您将第一个代码段转换为:
final byte a = 3;
final byte b = 8;
byte c = a + b;
Run Code Online (Sandbox Code Playgroud)
它汇编!由于你的两个字节是final 并且它们的表达式是常量,这次,编译器可以确定结果在首次初始化时适合一个字节.
但是,这不会编译:
final byte a = 127; // Byte.MAX_VALUE
final byte b = 1;
byte c = a + b // Nope...
Run Code Online (Sandbox Code Playgroud)
编译器将出现"可能的精度损失"错误.