3

我需要使用一个无符号字节数组。我需要通过网络将某些字符发送到服务器,其中一些字符大于 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

4 回答 4

10

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

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

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

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

如果您想知道字节如何同时表示负数和正数,请阅读这篇关于Java 中二进制补码算法的文章

于 2013-02-25T18:19:59.143 回答
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);
于 2013-02-25T18:31:44.537 回答
2

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

于 2013-02-25T18:20:02.233 回答
1

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

于 2013-02-25T18:26:15.457 回答