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

标签 java

查询 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 部分。

最佳答案

首先,Assignment Conversions, JLS 5.2涵盖了可以分配的值。

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable.

对于 byte a = 0;,常量表达式是 int 0,它被缩小为 byte .

接下来,Invocation Contexts, JLS 5.3涵盖哪些值可以传递给方法。

Neither strict nor loose invocation contexts include the implicit narrowing of integer constant expressions which is allowed in assignment contexts.

因此,您的代码存在调用上下文(方法调用)中不允许的常量表达式缩小转换的编译器错误。

setByte(0); // no implicit narrowing conversion, even if it's a constant expression
void setByte(byte b){}

您的代码 128 - 1 是一个缩小到 byte 的常量表达式。

但是,2147483648 - 1 是不允许的,因为 2147483648 本身 is not a valid int literal, Section 3.10.1, "Integer Literals" .

It is a compile-time error if the decimal literal 2147483648 appears anywhere other than as the operand of the unary minus operator; or if a decimal literal of type int is larger than 2147483648 (231).

如果你真的想使用一个不必要的复杂表达式来初始化一个int,你可以使用一个long字面量来使表达式合法:

2147483648L - 1

但是您必须明确地将表达式转换为 int;没有从任何比 int 宽的东西隐式缩小到 int:

(int) (2147483648L - 1)

奇怪的是,您不必在表达式两边放置圆括号以便强制转换应用于整个表达式,尽管为了清楚起见我强烈建议使用圆括号。

(int) 2147483648L - 1  // It's 2147483647!

int范围之外的long文字上的int将产生-2147483648,一个有效的int 值。此处减 1 涉及负方向溢出,产生预期值 2147483647。

关于java - 为什么我们不能将整数文字作为参数传递给以字节作为形式参数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57858640/

相关文章:

java - 连续输入(输入/扫描仪)两个相同的数字以打破循环 "while"Java

java - 如何设置 JRadioButtons 的属性并将其应用于所有属性?

java - 创建Android ArrayList错误

java - 从 LinkedList 中删除重复项时遇到问题

java - 如何有效地获取目录中的(某些)文件名

java - 何时使用不同的 SecurityContextHolder 策略?

java - 我正在尝试检查 Anagram

java - 如何停止该线程内的线程/计时器?

java.util.logging.SimpleFormatter.format 毫秒

java - 单元测试中的初始化