Java 将无符号字节转换为有符号字节

Java 将无符号字节转换为有符号字节,java,byte,unsigned,signed,Java,Byte,Unsigned,Signed,在java中,有没有一种简单而优雅的方法可以将无符号字节值转换为有符号字节值?例如,如果我只有int值240(二进制(24位+11110000)=32位),那么如何获取该int的有符号值呢?Java没有无符号值,除了char。考虑这个片段: byte val = (byte)255; System.out.println(String.valueOf(val)); 结果将是-1,因为最低的8位被复制到字节变量。在Java中,除了char之外,所有基元类型都是有符号的。不能有无符号字节。 您可以

在java中,有没有一种简单而优雅的方法可以将无符号字节值转换为有符号字节值?例如,如果我只有int值240(二进制(24位+11110000)=32位),那么如何获取该int的有符号值呢?

Java没有无符号值,除了
char
。考虑这个片段:

byte val = (byte)255;
System.out.println(String.valueOf(val));

结果将是-1,因为最低的8位被复制到字节变量。

在Java中,除了
char
之外,所有基元类型都是有符号的。不能有无符号字节。 您可以做的唯一一件事是将无符号字节强制转换为int,以便读取其正确的值:

int a = b & 0xff
如果您想在字节类型中存储无符号字节值,显然可以,但每次需要“处理”它时,只需记住如上所示再次强制转换它

public int getUnsignedByte(byte[] bytes, int offset) {
    return (bytes[offset] & 0xFF);
}

应该这样做。

Java只支持有符号字节,因此每当您在字节中放置值时,都假定它是有符号的

byte b = (byte) 240;
但是,如果要存储无符号字节,则需要自己处理。(即Java不支持,但您可以做到)

对于像+,-,*,>,=,!=,~您不需要更改任何内容,对于需要进行微小调整的操作,以及对于/、%之类的操作,您需要使用更大的数据类型


一种常见的替代方法是使用较大的数据类型(如
int
)来存储值0-255。这样做没有太大的缺点。

以下是如何存储和转换无符号字节值:

byte b = (byte) 144; // binary value = 10010000
如果将
b
转换为
int
,则会发生以下情况:

int i = b;
System.out.println("value: "+i);  
System.out.println("binary: " + Integer.toBinaryString(i));
输出:

value: -112 <- Incorrect value
binary: 11111111111111111111111110010000 
现在,我们可以使用按位
&
运算符将最左边的24位“归零”,只剩下原来的8位

int unsignedValue = b & mask; // value = 144
我们的初始值144已经恢复,可以安全地转换回一个字节:

byte original = (byte) unsignedValue;

我明白你的意思。java中的int是32位的,所以会复制最低的8位,对吗?是的。“最低”是指具有最低位置值(2^n)的位。因此,位置值为2^0-2^7的位被复制,但值为2^8或更高的位被丢弃。因为它是java,所以您不必担心endianness。此外,如果您想处理无符号值,只需执行@ostefano编写的操作即可——在任何情况下,java都会在内部对int、short和bytes执行整数算术。“java没有无符号值。”:not true
char
未签名。这会产生什么影响?这是否仅仅意味着,如果b是32位int,那么带11111111的“and”将复制最低的8位?谢天谢地,我忘了提到“b”是保存在有符号字节类型中的无符号字节(唯一可用的)。您始终可以将无符号字节存储在有符号字节类型中,但每次需要进行一些计算时,都需要执行上述转换。如果你只需要检查它的部分,你不需要。我仍然不同意你的看法。为什么要将字节b与0xff相加?这意味着将值向上转换为另一种类型(在java中不能将0xff分配给字节变量),并丢弃除8个最右边的位(存储该值的位置)以外的所有位。“在java中,所有基元类型都有符号。”:不正确<代码>字符未签名。
byte original = (byte) unsignedValue;