Java:为什么我会收到错误消息“类型不匹配:无法将 int 转换为字节”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/81392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:04:35  来源:igfitidea点击:

Java: why do I receive the error message "Type mismatch: cannot convert int to byte"

javatype-conversionbytetype-mismatch

提问by Brad Richards

If you declare variables of type byte or short and attempt to perform arithmetic operations on these, you receive the error "Type mismatch: cannot convert int to short" (or correspondingly "Type mismatch: cannot convert int to byte").

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

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

In this example, the compile error is on the third line.

在这个例子中,编译错误在第三行。

采纳答案by Brad Richards

Although the arithmetic operators are defined to operate on any numeric type, according the Java language specification (5.6.2 Binary Numeric Promotion), operands of type byte and short are automatically promoted to int before being handed to the operators.

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

To perform arithmetic operations on variables of type byte or short, you must enclose the expression in parentheses (inside of which operations will be carried out as type int), and then cast the result back to the desired type.

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

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

Here's a follow-on question to the real Java gurus: why? The types byte and short are perfectly fine numeric types. Why does Java not allow direct arithmetic operations on these types? (The answer is not "loss of precision", as there is no apparent reason to convert to int in the first place.)

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

Update: jrudolph suggests that this behavior is based on the operations available in the JVM, specifically, that only full- and double-word operators are implemented. Hence, to operator on bytes and shorts, they must be converted to int.

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

回答by David Sykes

The answer to your follow-up question is here:

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

operands of type byte and short are automatically promoted to int before being handed to the operators

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

So, in your example, aand bare both converted to an intbefore being handed to the + operator. The result of adding two ints together is also an int. Trying to then assign that intto a bytevalue causes the error because there is a potential loss of precision. By explicitly casting the result you are telling the compiler "I know what I am doing".

因此,在您的示例中,abint在传递给 + 运算符之前转换为 an 。两个ints相加的结果也是int。尝试将其分配int给一个byte值会导致错误,因为可能会损失精度。通过显式转换结果,您是在告诉编译器“我知道我在做什么”。

回答by jrudolph

I think, the matter is, that the JVM supports only two types of stack values: word sized and double word sized.

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

Then they probably decided that they would need only one operation that works on word sized integers on the stack. So there's only iadd, imul and so on at bytecode level (and no operators for bytes and shorts).

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

So you get an int value as the result of these operations which Java can't safely convert back to the smaller byte and short data types. So they force you to cast to narrow the value back down to byte/short.

因此,这些操作的结果是一个 int 值,Java 无法安全地将其转换回较小的字节和短数据类型。所以他们强迫你将值缩小回字节/短。

But in the end you are right: This behaviour is not consistent to the behaviour of ints, for example. You can without problem add two ints and get no error if the result overflows.

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

回答by Tom Hawtin - tackline

The Java language always promotes arguments of arithmetic operators to int, long, float or double. So take the expression:

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

a + b

where a and b are of type byte. This is shorthand for:

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

(int)a + (int)b

This expression is of type int. It clearly makes sense to give an error when assigning an int value to a byte variable.

该表达式的类型为 int。在将 int 值分配给字节变量时给出错误显然是有意义的。

Why would the language be defined in this way? Suppose a was 60 and b was 70, then a+b is -126 - integer overflow. As part of a more complicated expression that was expected to result in an int, this may become a difficult bug. Restrict use of byte and short to array storage, constants for file formats/network protocols and puzzlers.

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

There is an interesting recording from JavaPolis 2007. James Gosling is giving an example about how complicated unsigned arithmetic is (and why it isn't in Java). Josh Bloch points out that his example gives the wrong example under normal signed arithmetic too. For understandable arithmetic, we need arbitrary precision.

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