为什么我们不能将整数文字作为参数传递给以字节作为形式参数的方法

查询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){}

查询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 ?

请解释一下,并指出定义这些规则的 JLS 部分。


翻阅古今
浏览 81回答 1
1回答

ABOUTYOU

首先,赋值转换,JLS 5.2涵盖了可以赋值的值。此外,如果表达式是byte、short、char或 类型的常量表达式 (§15.28) 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){}您的代码128 - 1是一个缩小为byte.但是,2147483648 - 1由于2147483648它本身不是有效的int文字,因此被禁止,第 3.10.1 节“整数文字”。如果十进制文字 2147483648 出现在除一元减运算符的操作数之外的任何位置,则会出现编译时错误;或者如果 int 类型的十进制文字大于 2147483648 (2 31 )。如果您确实想使用不必要的复杂表达式来初始化int,您可以使用long文字使表达式合法:2147483648L - 1但随后您必须将表达式显式转换为int; 不存在从任何比 更宽的int内容到 的隐式缩小int:(int) (2147483648L - 1)奇怪的是,您不必在表达式周围放置括号,以便强制转换适用于整个表达式,尽管为了清楚起见,我强烈建议使用括号。(int) 2147483648L - 1  // It's 2147483647!对超出范围的文字int进行强制转换将产生 -2147483648,一个有效值。这里减 1 涉及负方向溢出,产生预期值 2147483647。longintint
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java