无符号字节,实际上就是 0~255。但Java没有无字节符号数据类型,byte
是8位带符号(正和负)数据类型,其值从-128(-27)到127(27-1)。
在Java中如何将有符号字节转换为无符号字节?
byte b = -1;
咱们拿-1
为例,其二进制可表示为:
1111 1111
首先,我们可以将byte
(8位)转换为int
(32位)。
// 代表 byte -1(8位)
1111 1111
// byte --> int
// 代表 int -1(32位)
1111 1111 1111 1111 1111 1111 1111 1111
接着,把 int -1(32位)和0xff
进行位与&
运算
1111 1111 1111 1111 1111 1111 1111 1111 // int -1(32位)
// &
0000 0000 0000 0000 0000 0000 1111 1111 // 0xff(32位)
// =
0000 0000 0000 0000 0000 0000 1111 1111 // 屏蔽掉左边24位,以获取最后8位
我们取出最后8位,并转换为十进制:
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|
27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
1×27 + 1×26 + 1×25 + 1×24 + 1×23 + 1×22 + 1×21 + 1×20
= 128+64+32+16+8+4+2+1
= 255
来看看 Java 代码如何编写:
byte b = -1;
int number = b & 0xff;
System.out.println(number);
// 输出 255
到这里,咱们就 -128 ~ 127 计算整理出一个《有符号与无符号字节对照表》
字节 | 无符号字节 |
---|---|
1 | 1 |
2 | 2 |
… | … |
127 | 127 |
-128 | 128 |
-127 | 129 |
-126 | 130 |
… | … |
-2 | 254 |
-1 | 255 |
为什么要将8位
byte
转换为32位int
?Java使用二进制补码来表示带符号的数字(正、负号),最左边的位表示符号(0表示正数,1表示负数),其余位表示
111 1111
…000 0001
,即-128 ~ 127
;8位byte,只有7位用于存储,剩余的128 ~ 255
无法容纳在一个byte
中,因此我们需要将期转换为32位无符号整数,以获得更多空间(位)。
Java 8
Java 8 以后针对byte
,java.lang.Byte
提供了Byte.toUnsignedInt(byte x)
和Byte.toUnsignedLong(byte x)
,采用了与我们上面相同的方法,将有符号字节转换为无符号整数。
image.png