我看到有人问错误“类型不匹配:无法将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:截图更新]
答案 0 :(得分:10)
你有一点,怀疑这是关于签名的整数。在Java中,所有整数类型(byte
,short
,int
,long
)始终都是签名的。 Java使用了两个补码来存储带符号(读“全部”)的值。这基本上意味着,如果任何类型的第一位(不是文字中指定的第一位,但存储的第一位)是1,则该数字为负。如果它为0,则为正。
第二件重要的事情是:Java中没有BYTE文字。有int
个文字和long
文字。写下的每个nubmer(无论是二进制(0b前缀),八进制(0前缀),十进制(无前缀)还是十六进制(0x前缀))都是整数文字,除非您附加L
(小写或大写),它是long
。无法直接记下任何short
或byte
。
现在,这意味着,您记下的所有示例都是先创建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