查询1:
byte a = 0; // int to byte implicit conversion happens, correct!, no CTE [compile time error]
setByte(0); // CTE!, why ? implicit conversion do not happen here
void setByte(byte b){}
Run Code Online (Sandbox Code Playgroud)
查询2:
byte b_byte = 128 - 1; // integer literal computation results to 127 int which implicitly casts to byte and as 127 is in range of byte so no CTE, Correct!
int a_int = 2147483647; // in range of int, so no CTE
int b_int = 2147483648 - 1; // still in range of int but CTE, why ?
Run Code Online (Sandbox Code Playgroud)
请解释,也请指向定义这些规则的JLS部分。
首先,分配转换,JLS 5.2涵盖了可以分配的值。
此外,如果表达式类型的常量表达式(§15.28) ,
byte,short,char或int:
- 如果变量的类型为
byte,short或char,并且常量表达式的值在变量的类型中可表示,则可以使用缩窄的原始转换。
因为byte a = 0;常量表达式是,因此将int 0其缩小为a byte。
接下来,调用上下文,JLS 5.3涵盖了可以将哪些值传递给方法。
严格的或宽松的调用上下文都不包含在赋值上下文中允许的整数常量表达式的隐式缩小。
因此,对于调用上下文(方法调用)中不允许的常量表达式缩小转换,您的代码存在编译器错误。
setByte(0); // no implicit narrowing conversion, even if it's a constant expression
void setByte(byte b){}
Run Code Online (Sandbox Code Playgroud)
您的代码128 - 1是一个缩小为的常量表达式byte。
但是,2147483648 - 1不允许这样做,因为2147483648它本身不是有效的int文字,第3.10.1节“整数文字”。
如果十进制文字2147483648除了作为一元减运算符的操作数之外的其他任何地方出现,则是编译时错误;或如果int类型的十进制文字大于2147483648(2 31)。
如果您确实想使用不必要的复杂表达式来初始化int,则可以使用long文字使表达式合法:
2147483648L - 1
Run Code Online (Sandbox Code Playgroud)
但是您必须将表达式显式转换为int;没有任何隐含的缩小,从任何更宽的范围int到int:
(int) (2147483648L - 1)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,尽管为了清晰起见,我强烈建议使用括号,但您不必在表达式周围加上括号,以便将转换应用于整个表达式。
(int) 2147483648L - 1 // It's 2147483647!
Run Code Online (Sandbox Code Playgroud)
在int对铸造long的文本,这超出int范围,将产生-2147483648,一个有效的int值。此处减去1将导致负方向上的溢出,从而产生预期值2147483647。
| 归档时间: |
|
| 查看次数: |
55 次 |
| 最近记录: |