如果您声明 byte 或 Short 类型的变量并尝试对这些变量执行算术运算,您会收到错误“类型不匹配:无法将 int 转换为 Short”(或相应的“类型不匹配:无法将 int 转换为 byte”)。

byte a = 23;
byte b = 34;
byte c = a + b;

在此示例中,编译错误位于第三行。

有帮助吗?

解决方案

尽管算术运算符被定义为对任何数字类型进行操作,但根据 Java 语言规范(5.6.2 二进制数字提升),byte 和 Short 类型的操作数在传递给运算符之前会自动提升为 int。

要对 byte 或 Short 类型的变量执行算术运算,必须将表达式括在括号中(在括号内将以 int 类型执行运算),然后将结果转换回所需的类型。

byte a = 23;
byte b = 34;
byte c = (byte) (a + b);

这是向真正的 Java 大师提出的一个后续问题:为什么?byte 和short 类型是非常好的数字类型。为什么 Java 不允许对这些类型进行直接算术运算?(答案不是“精度损失”,因为首先没有明显的理由转换为 int。)

更新:jrudolph 认为此行为基于 JVM 中可用的操作,特别是仅实现全字和双字运算符。因此,要对字节和短整型进行操作,必须将它们转换为 int。

其他提示

您的后续问题的答案在这里:

byte 和 Short 类型的操作数在传递给运算符之前会自动提升为 int

所以,在你的例子中, ab 都转换为 int 在交给 + 运算符之前。两个相加的结果 int在一起也是一个 int. 。然后尝试分配 int 到一个 byte value 会导致错误,因为存在潜在的精度损失。通过显式转换结果,您可以告诉编译器“我知道我在做什么”。

我认为,问题是 JVM 仅支持两种类型的堆栈值:字大小和双字大小。

然后他们可能决定只需要一项对堆栈上字大小的整数起作用的操作。所以在字节码级别只有 iadd、imul 等(并且没有字节和短整型的运算符)。

因此,您会得到一个 int 值作为这些操作的结果,Java 无法安全地将其转换回较小的字节和短数据类型。因此,它们迫使您将值缩小到字节/短。

但最终你是对的:例如,此行为与整数的行为不一致。您可以毫无问题地添加两个整数,并且如果结果溢出也不会出现错误。

Java 语言总是将算术运算符的参数提升为 int、long、float 或 double。所以采用表达式:

a + b

其中a和b是字节类型。这是以下内容的简写:

(int)a + (int)b

这个表达式的类型是int。将 int 值分配给 byte 变量时给出错误显然是有意义的。

为什么要以这种方式定义语言?假设a是60,b是70,那么a+b是-126——整数溢出。作为预计会产生 int 的更复杂表达式的一部分,这可能会成为一个困难的错误。限制使用字节和短数组存储、文件格式/网络协议和谜题的常量。

JavaPolis 2007 有一段有趣的录音。James Gosling 举了一个例子来说明无符号算术有多么复杂(以及为什么 Java 中没有这种算术)。乔什·布洛赫 (Josh Bloch) 指出,他的示例在正常有符号算术下也给出了错误的示例。为了可以理解的算术,我们需要任意精度。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top