Java和无符号字节

时间:2013-02-25 18:13:22

标签: java byte unsigned

我需要使用无符号字节数组。我需要通过网络将某些字符发送到服务器,其中一些字符大于127.

我有以下代码的简化版本,试图理解这个概念:

int i= 160;
byte j = (byte) i;
System.out.println((byte)i);
System.out.println(j);

,这给出了一个输出: -96 -96

我需要打印160.因为服务器期望一个字节为160,如果它接收-96,它不接受该值。我使用int的原因是当我在阅读如何解决问题时,我经常遇到使用int的建议,但我不太明白,因为我需要我的数组是类型为byte

这是我发送数组的代码的一部分:

public boolean send(byte[] data) {
    try {
     out.write(data); // Write the data to the outStream
     out.flush();
    } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false; // Return false if the TCP Transmit failed 
// }
return false;
}

如果有人可以帮助我,我会非常感激。

4 个答案:

答案 0 :(得分:10)

Java在有符号和无符号字节之间没有区别。以下两个都将为一个字节分配相同的值:

byte i = (byte)160;
byte j = (byte)-96;

作为开发人员,您可以在打印时将其视为已签名或未签名。默认是打印它们已签名,但您可以强制它们通过无符号方式将它们转换为整数来打印无符号。

System.out.println(i); // -96
System.out.println(0xff&i); // 160

如果您想知道字节如何同时代表负数和正数,请阅读two’s complement arithmetic in Java上的这篇文章

答案 1 :(得分:2)

发送-96是正确的行为。有符号和无符号字节在打印时是不同的,但不是在位表示中,并且当它们被另一台服务器接收时它们不应该有所不同。

答案 2 :(得分:2)

没有System.out.println(byte)。最接近的是System.out.println(int)。这意味着您的字节值将转换为整数。转换扩展了高位,导致负数。

以下代码将证明我的观点:

byte[] data =
{
    (byte)0x01,
    (byte)0x02,
    (byte)0x7F,
    (byte)0x80
};

for (byte current : data)
{
    String output = String.format("0x%x, 0x%x", current, (int)current);
    System.out.println(output);
}

如果要使用System.out.println查看字节值,请屏蔽整数值的前三个字节,如下所示:

System.out.println(((0x000000FF & (int)current);

答案 3 :(得分:1)

字节本身没有签名或未签名。当应用某些操作时(例如,比较为0以确定符号),它们被解释为这样。操作可以是有符号和无符号的,而在Java中,只有签名的字节操作可用。所以你引用的代码对于这个问题没用 - 它发送字节但不做任何操作。更好地显示接收字节的代码。一个正确且方便的方法是使用java.io.InputStream.read()方法,该方法将字节作为0到255范围内的整数返回。