简体   繁体   English

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

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

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.在这个例子中,编译错误在第三行。

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二进制数字提升),字节和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? 这是真正的Java专家的一个后续问题:为什么? The types byte and short are perfectly fine numeric types. byte和short类型是完美的数字类型。 Why does Java not allow direct arithmetic operations on these types? 为什么Java不允许对这些类型进行直接算术运算? (The answer is not "loss of precision", as there is no apparent reason to convert to int in the first place.) (答案不是“精度下降”,因为没有明显的理由首先将其转换为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. 更新:jrudolph建议此行为基于JVM中可用的操作,尤其是仅实现全字和双字运算符。 Hence, to operator on bytes and shorts, they must be converted to int. 因此,对于字节和短裤运算符,必​​须将它们转换为int。

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, a and b are both converted to an int before being handed to the + operator. 因此,在您的示例中,将ab都转换为int然后再交给+运算符。 The result of adding two int s together is also an int . 将两个int相加的结果也是int Trying to then assign that int to a byte value causes the error because there is a potential loss of precision. 然后尝试将int分配给byte值会导致错误,因为可能会丢失精度。 By explicitly casting the result you are telling the compiler "I know what I am doing". 通过显式转换结果,您将告诉编译器“我知道我在做什么”。

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. 因此,您将得到一个int值,这些操作是Java无法安全地转换回较小字节和short数据类型的结果。 So they force you to cast to narrow the value back down to byte/short. 因此,它们迫使您强制将值缩小到字节/短。

But in the end you are right: This behaviour is not consistent to the behaviour of ints, for example. 但是最后您是对的:例如,此行为与int的行为不一致。 You can without problem add two ints and get no error if the result overflows. 您可以毫无疑问地添加两个整数,并且如果结果溢出也不会出错。

The Java language always promotes arguments of arithmetic operators to int, long, float or double. Java语言始终将算术运算符的参数提升为int,long,float或double。 So take the expression: 因此,采用以下表达式:

a + b

where a and b are of type byte. 其中a和b是字节类型。 This is shorthand for: 这是以下内容的简写:

(int)a + (int)b

This expression is of type int. 此表达式的类型为int。 It clearly makes sense to give an error when assigning an int value to a byte variable. 将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. 假设a为60而b为70,则a + b为-126-整数溢出。 As part of a more complicated expression that was expected to result in an int, this may become a difficult bug. 作为可能导致int的更复杂表达式的一部分,这可能会成为一个困难的错误。 Restrict use of byte and short to array storage, constants for file formats/network protocols and puzzlers. 限制使用字节和数组存储的简短形式,文件格式/网络协议和拼图的常量。

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). JavaPolis 2007上有一个有趣的记录。JamesGosling给出了一个例子,说明无符号算术有多么复杂(以及为什么Java中没有它)。 Josh Bloch points out that his example gives the wrong example under normal signed arithmetic too. 乔什·布洛赫(Josh Bloch)指出,他的例子在正常的有符号算术下也给出了错误的例子。 For understandable arithmetic, we need arbitrary precision. 对于可理解的算法,我们需要任意精度。

In Java Language Specification (5.6.2 Binary Numeric Promotion):在 Java 语言规范(5.6.2 二进制数字提升)中:

1 If any expression is of type double, then the promoted type is double, and other expressions that are not of type double undergo widening primitive conversion to double. 1 如果任何表达式为 double 类型,则提升的类型为 double,其他非 double 类型的表达式经历扩展原始转换为 double。

2 Otherwise, if any expression is of type float, then the promoted type is float, and other expressions that are not of type float undergo widening primitive conversion to float. 2 否则,如果任何表达式是 float 类型,则提升的类型是 float,并且其他非 float 类型的表达式经历扩展原始转换为 float。

3 Otherwise, if any expression is of type long, then the promoted type is long, and other expressions that are not of type long undergo widening primitive conversion to long. 3 否则,如果任何表达式为 long 类型,则提升的类型为 long,并且其他非 long 类型的表达式经历扩展原始转换为 long。

4 Otherwise, none of the expressions are of type double, float, or long. 4 否则,所有表达式都不是 double、float 或 long 类型。 In this case, the promoted type is int, and any expressions that are not of type int undergo widening primitive conversion to int.在这种情况下,提升的类型是 int,并且任何不是 int 类型的表达式都会经历扩展原始转换为 int。

Your code belongs to case 4. variables a and b are both converted to an int before being handed to the + operator.您的代码属于案例 4。变量ab在交给+运算符之前都转换为int The result of + operation is also of type int not byte +操作的结果也是int类型而不是byte

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “类型不匹配:无法将int转换为字节” - “Type mismatch: cannot convert int to byte” 类型不匹配:Java 代码中无法从 int 转换为 int[] 错误 - Type mismatch: cannot convert from int to int[] error in Java code Java类型不匹配-无法从构造函数中的int [] []错误转换 - Java Type mismatch - cannot convert from int[][] error in constructor 类型不匹配:无法使用三元运算符从int转换为字节 - Type mismatch: cannot convert from int to byte using ternary operator 为什么会出现此错误“类型不匹配:无法从序列化转换为T”? - Why do I get this error “Type mismatch: cannot convert from Serializable to T”? 错误:类型不匹配:无法使用Java Xtend从(Object)=> int转换为int - Error: Type mismatch: cannot convert from (Object)=>int to int using Java Xtend ResultSet不适用于INSERT查询? 错误消息:类型不匹配:无法从int转换为String - ResultSet is not for INSERT query? Error message: Type mismatch: cannot convert from int to String Java 编译错误 - 类型不匹配:无法从 String 转换为 int - Java Compilation Error- Type mismatch: cannot convert from String to int 错误:类型不匹配:无法从java.lang.String转换为int - Error: Type mismatch: cannot convert from java.lang.String to int 在Java中的对象数组内初始化整数时,出现“类型不匹配:无法从int转换为Object”错误 - Getting “Type mismatch: cannot convert from int to Object” error at the time of initiation of integer inside Object Array in java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM