Java:为什么我会收到错误消息;类型不匹配:无法将int转换为byte";

Java:为什么我会收到错误消息;类型不匹配:无法将int转换为byte";,java,type-conversion,byte,type-mismatch,Java,Type Conversion,Byte,Type Mismatch,如果声明byte或short类型的变量并尝试对其执行算术运算,则会收到错误“类型不匹配:无法将int转换为short”(或相应的“类型不匹配:无法将int转换为byte”) 在本例中,编译错误在第三行。尽管算术运算符定义为对任何数字类型进行操作,但根据Java语言规范(5.6.2二进制数字提升),byte和short类型的操作数在交给运算符之前会自动提升为int 要对byte或short类型的变量执行算术运算,必须将表达式括在括号内(在括号内,运算将作为int类型执行),然后将结果转换回所需的类

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


在本例中,编译错误在第三行。

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

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

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


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

后续问题的答案如下:

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


因此,在您的示例中,
a
b
在交给+运算符之前都转换为
int
。将两个
int
s相加的结果也是
int
。然后尝试将该
int
赋值给
byte
值会导致错误,因为可能会丢失精度。通过显式转换结果,您告诉编译器“我知道我在做什么”。

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

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

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


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

Java语言总是将算术运算符的参数提升为int、long、float或double。那么,就拿这个表达来说:

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

(int)a + (int)b
此表达式属于int类型。将int值赋给字节变量时,给出错误显然是有意义的

为什么要这样定义语言?假设a是60,b是70,那么a+b是-126-整数溢出。作为一个更复杂的表达式的一部分,它可能会导致int,这可能会成为一个困难的bug。限制使用字节和短到阵列存储、文件格式/网络协议常量和谜题


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

IIRC JVM将字节和短字符存储为int,因此使用这两种数据类型通常没有什么好处。当然,我意识到你所做的事情比你的例子要复杂得多,并且可能有一个很好的理由。我想这是因为你的表现。在某些cpu中,使用比cpu寄存器小的操作数可能更昂贵。可能它甚至使用了32位int来存储byte和short,以使它们在内存中保持对齐。因为我发现-这些操作是在CPU寄存器中执行的,但是是的,它们是32位对齐的。您也不能对字符执行+运算符
字节c=(字节)(a+b)
;转换后,此表达式将如下所示,其中57为byte类型。但是,由于数字提升表示所有字节、短字符和字符文字都转换为int,所以这个字节57将被提升为int 57。因此,在这个意义上,编译器仍然应该给出一个错误,但它不会。为什么?
(int)a + (int)b