Java “类型不匹配:无法将 int 转换为字节”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20026942/
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-12 22:25:58  来源:igfitidea点击:

“Type mismatch: cannot convert int to byte”

javabytebit-manipulation

提问by Weishi Zeng

I saw people asking questions about the error "Type mismatch: cannot convert int to byte". But they are mostly caused by arithmetic operations involved.

我看到人们询问有关错误“类型不匹配:无法将 int 转换为字节”的问题。但它们大多是由所涉及的算术运算引起的。

Here is my case:
(This happens when I want to play with bits in Eclipse Kepler)

这是我的情况:(
当我想在 Eclipse Kepler 中使用位时会发生这种情况)

//java 7 binary literals

byte a =  0b01111111; //8-bit it compiles 

byte b =  0b10000000;  //8-bit error: Type mismatch: cannot convert int to byte.                        

byte c =  (byte) 0b10000000; //8-bit it works fine if casted.

The thing is that if it is 8 bits and the highest digit is 1, then compiler gives error. I want to know why. The prefix 0b means it is a binary literal so why the compiler take the highest digit as a signed int digit or something like that?

问题是,如果它是 8 位并且最高位是 1,那么编译器就会出错。我想知道为什么。前缀 0b 表示它是一个二进制文字,那么为什么编译器将最高数字作为有符号整数数字或类似的数字?

Thanks for answering.

谢谢回答。

[Edit3:]

[编辑3:]

byte a = -128; //a = 0xFF = 11111111 (8 bits), compiler says ok.
byte b = 0b11111111; //compiler error

[Edit2: bitwise & operation somehow triggers the error as well]

[Edit2:按位&操作也会以某种方式触发错误]

byte a = 0b00000000;  //8 bits
a = (a&0xFF);  //gives same error: Type mismatch: cannot convert int to byte
a = (byte)(a&0xFF); //it is fine to cast

[Edit1: screenshot updated] enter image description here

[Edit1:截图更新] 在此处输入图片说明

enter image description here

在此处输入图片说明

采纳答案by Johannes H.

You got a point, suspecting this is about signed integers. In Java, ALL integers types (byte, short, int, long) are ALWAYS signed. Java used two's complement to store signed (read "all") values. That basically means, that if the first bit of any type (not first bit specified in the literal, but first bit stored) is 1, the number is negative. If it's 0, it's positive.

你有一点,怀疑这是关于有符号整数。在 Java 中,所有整数类型 ( byte, short, int, long) 总是有符号的。Java 使用二进制补码来存储有符号(读取“所有”)值。这基本上意味着,如果任何类型的第一位(不是文字中指定的第一位,而是存储的第一位)为 1,则该数字为负数。如果为 0,则为正。

Second thing of importance is: There are no BYTE literals in Java. There are intliterals, and longliterals. Every nubmer written down (be it in binary (0b prefix), octal (0 prefix), decimal (no prefix) or hex (0x prefix)) is an integer literal, unless you append an L(either lowercase or uppercase), it's long. There is no way to write down any shortor bytedirectly.

第二件重要的事情是:Java 中没有 BYTE 字面量。有int文字,也有long文字。每个写下来的数字(无论是二进制(0b 前缀)、八进制(0 前缀)、十进制(无前缀)还是十六进制(0x 前缀))都是一个整数文字,除非你附加一个L(小写或大写),它是long. 没有办法写下任何shortbyte直接。

Now, that means, that all those examples you wrote down, are creating an intfirst. You don't create bytes there.

现在,这意味着,您写下的所有示例都是int第一个。你不会byte在那里创建s。

So, the last part is, what happens if you try to store that intinside a byte- without casting or with casting. If you are casting explicitely you basically tell Java to just ignore any bits that don't fit. They will be cut - even if this changes the value of the number (for examples, see below). If you don't cast, bits will still be cut. But Java won't do that, if it changes the value - to make sure you really mean what you're doing.

所以,最后一部分是,如果您尝试将其存储intbyte- 不进行转换或进行转换时会发生什么。如果您明确地进行转换,您基本上是告诉 Java 忽略任何不适合的位。它们将被削减 - 即使这会改变数字的值(例如,见下文)。如果你不投射,位仍会被切割。但是 Java 不会这样做,如果它更改了值 - 以确保您真正做到了您正在做的事情。

To link this all to the exmamples from the question:
int 0b01111111is 127
byte 0b01111111is 127
-> conversion possible without any overflow, so Java will do it even without an explicit cast

将所有这些链接到问题中的示例:
int 0b01111111is 127
byte 0b01111111is 127
-> 转换可能没有任何溢出,所以即使没有显式转换,Java 也会这样做

int 0b10000000is 128
byte 0b10000000is -128
-> An overflow occrus when converting, so Java will throw an error if there is no explicit cast.

int 0b10000000is 128
byte 0b10000000is -128
-> 转换时出现溢出,因此如果没有显式转换,Java 将抛出错误。

回答by richard

I think bytes in java are signed, which would make 0b10000000 out of range. 127 would be the largest byte possible, the reason being the two's compliment representation of negative numbers.

我认为 java 中的字节是有符号的,这会使 0b10000000 超出范围。127 将是可能的最大字节,原因是负数的二进制补码表示。

回答by user3489270

Byte variables CAN hold the value 0b1000000, but since they are signed, that represents the integer value -128. The reason it can't convert the literal is that when you write it as a literal with no cast, the compiler sees it as (int) 0b10000000 which is the integer value POSITIVE 128.

字节变量可以保存值 0b1000000,但由于它们是有符号的,因此表示整数值 -128。它无法转换文字的原因是,当您将其编写为没有强制转换的文字时,编译器将其视为 (int) 0b10000000,即整数值 POSITIVE 128。

Any integer value above 127 is out of bounds for a byte, since bytes are signed and can only hold integer values from -128 to 127. That's where the overflow comes in (to hold 128, you'd need a ninth bit for the sign). Any time a signed value has 1 as its most significant bit, it represents a negative number, so in order to put a number like 0b10000000 into a byte, you would need to represent a negative value in your literal. For example, the value -128 would be equivalent to the int 0b11111111111111111111111110000000, so you would need to use that as your literal, or else, much simpler, just explicitly cast it as a byte, like: (byte) 0b10000000

任何大于 127 的整数值都超出了字节的范围,因为字节是有符号的,并且只能保存从 -128 到 127 的整数值。这就是溢出的来源(要保存 128,您需要第 9 位作为符号)。任何有符号值的最高有效位为 1 时,它表示一个负数,因此为了将 0b10000000 之类的数字放入一个字节中,您需要在文字中表示一个负值。例如,值 -128 将等价于 int 0b1111111111111111111111110000000,因此您需要将其用作文字,或者更简单,只需将其显式转换为字节,例如: (byte) 0b10000000