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

时间:2013-11-17 03:42:40

标签: java byte bit-manipulation

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

这是我的情况:
(当我想在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.

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

感谢您的回答。

[EDIT3:]

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

[编辑2:按位&操作以某种方式触发错误]

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

[编辑1:截图更新] enter image description here

enter image description here

3 个答案:

答案 0 :(得分:10)

你有一点,怀疑这是关于签名的整数。在Java中,所有整数类型(byteshortintlong)始终都是签名的。 Java使用了两个补码来存储带符号(读“全部”)的值。这基本上意味着,如果任何类型的第一位(不是文字中指定的第一位,但存储的第一位)是1,则该数字为负。如果它为0,则为正。

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

现在,这意味着,您记下的所有示例都是先创建int。你没有在那里创建byte

所以,最后一部分是,如果你试图将int存储在byte内而不进行强制转换或使用强制转换,会发生什么。 如果你明确地进行演员,你基本上告诉Java只是忽略任何不适合的位。它们将被削减 - 即使这会改变数字的值(例如,见下文)。 如果你不投射,比特仍然会被削减。但是,如果它改变了价值,Java就不会这样做 - 确保你真正意味着你在做什么。

将此全部链接到问题的例外:
int 0b01111111是127 byte 0b01111111是127 - >转换可能没有任何溢出,所以即使没有显式转换,Java也会这样做

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

答案 1 :(得分:3)

我认为java中的字节是有符号的,这会使0b10000000超出范围。 127将是可能的最大字节,原因是负数的两个恭维表示。

答案 2 :(得分:1)

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

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