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

时间:2021-03-06 16:34:16

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中使用比特的时候)

//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:]

[Edit3:]

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: bitwise & operation也会触发错误]

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] “类型不匹配:不能将int转换为字节”

[Edit1截图更新):

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

3 个解决方案

#1


10  

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使用了2的补充来存储签名(读取“所有”)值。这基本上意味着,如果任何类型的第一个类型(不是在字面上指定的第一个字节,而是第一个存储的位)是1,那么这个数字是负数。如果是0,它是正的。

Second thing of importance is: There are no BYTE literals in Java. There are int literals, and long literals. 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 short or byte directly.

第二件重要的事情是:Java中没有字节文字。有整型文字和长字。每一个nubmer都是一个整数,除非你附加一个L(小写或大写),它是一个整数,除非你附加一个L(小写或大写),否则它是一个整数。没有办法直接写下任何短或字节。

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

这意味着,你写下的所有例子,都是先创建一个整数。你不会在那里创建字节。

So, the last part is, what happens if you try to store that int inside 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.

所以,最后一部分是,如果你试图在一个字节内存储这个int类型,而不需要进行浇注或转换。如果你是明确的,你基本上告诉Java忽略任何不适合的位。他们将被削减——即使这改变了数字的价值(例如,见下文)。如果你不投,位就会被裁掉。但是Java不会这样做,如果它改变了值——确保你真正的意思是你正在做的事情。

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

要将这一切与问题联系起来:int 0b01111111是127字节的0b01111111是127 ->转换可能没有任何溢出,所以Java将会做它,即使没有明确的cast。

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

int 0b10000000是128字节0b10000000是-128 ->当转换时溢出的occrus,所以如果没有显式的cast, Java将抛出一个错误。

#2


3  

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是最大可能的字节,原因是两个表示负数的表示。

#3


1  

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。它不能转换文字的原因是当你把它写成一个没有cast的文字时,编译器会把它看成是(int) 0b10000000,它是整数值正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位的符号)。任何时候,一个有符号的值都有一个最重要的位,它代表一个负数,所以为了把一个数字像0b10000000变成一个字节,你需要在你的文字中表示一个负值。例如,值-128将等于int 0b1111111111111111111111111111111110000000,所以您需要将它作为您的文字,或者其他更简单的,只是显式地将它转换为一个字节,比如:(字节)0b10000000。

#1


10  

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使用了2的补充来存储签名(读取“所有”)值。这基本上意味着,如果任何类型的第一个类型(不是在字面上指定的第一个字节,而是第一个存储的位)是1,那么这个数字是负数。如果是0,它是正的。

Second thing of importance is: There are no BYTE literals in Java. There are int literals, and long literals. 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 short or byte directly.

第二件重要的事情是:Java中没有字节文字。有整型文字和长字。每一个nubmer都是一个整数,除非你附加一个L(小写或大写),它是一个整数,除非你附加一个L(小写或大写),否则它是一个整数。没有办法直接写下任何短或字节。

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

这意味着,你写下的所有例子,都是先创建一个整数。你不会在那里创建字节。

So, the last part is, what happens if you try to store that int inside 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.

所以,最后一部分是,如果你试图在一个字节内存储这个int类型,而不需要进行浇注或转换。如果你是明确的,你基本上告诉Java忽略任何不适合的位。他们将被削减——即使这改变了数字的价值(例如,见下文)。如果你不投,位就会被裁掉。但是Java不会这样做,如果它改变了值——确保你真正的意思是你正在做的事情。

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

要将这一切与问题联系起来:int 0b01111111是127字节的0b01111111是127 ->转换可能没有任何溢出,所以Java将会做它,即使没有明确的cast。

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

int 0b10000000是128字节0b10000000是-128 ->当转换时溢出的occrus,所以如果没有显式的cast, Java将抛出一个错误。

#2


3  

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是最大可能的字节,原因是两个表示负数的表示。

#3


1  

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。它不能转换文字的原因是当你把它写成一个没有cast的文字时,编译器会把它看成是(int) 0b10000000,它是整数值正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位的符号)。任何时候,一个有符号的值都有一个最重要的位,它代表一个负数,所以为了把一个数字像0b10000000变成一个字节,你需要在你的文字中表示一个负值。例如,值-128将等于int 0b1111111111111111111111111111111110000000,所以您需要将它作为您的文字,或者其他更简单的,只是显式地将它转换为一个字节,比如:(字节)0b10000000。