Java中带有十六进制的字节

Posted

技术标签:

【中文标题】Java中带有十六进制的字节【英文标题】:Bytes in Java with hex 【发布时间】:2012-12-13 06:31:52 【问题描述】:

buffer 是一个字节缓冲区。我正在丢失 percision 错误。

    byte myPort = buffer.get(0); // Might need to change this depending on byte order
    switch(myPort)
        case 0xF1: // Chat service
            break;
        case 0xF2: // Voice service
            break;
        case 0xF3: // Video service
            break;
        case 0xF4: // File transfer service
            break;
        case 0xF5: // Remote login
            break;
    

显然,0xFF 在 java 中不是一个字节,它真的让我很困惑。我不知道我是否会丢失它,但 0xF 不是一个半字节,而 0xFF 不是一个字节吗?显然我的 ide netbeans 允许字节值一直到 127。这似乎是有符号值的问题,但我不知道为什么。

感谢您的帮助。

【问题讨论】:

你在哪里得到这个错误?另外,我在代码中看不到任何0xFF 的使用。该代码是否完整? 我在案例 0xF1 处收到错误,依此类推。这些案例给了我错误。这不是整个代码,而是代码中唯一相关的部分。 那是因为你的值 0xF1 不在字节范围内 - [-128, 127]。 Java中的字节是有符号的。 0xF1 等于 241 哈哈,谁知道呢。无符号字节在网络中对我来说更有意义,所以我不明白他们为什么不在 Java 中提供它。由于我是一名 C/C++ 程序员,因此转换为整数的想法让我感到畏缩。 【参考方案1】:

如 cmets 中所述,字节为 [-128 .. 127]。

您应该将字节从字节缓冲区转换为 int,以保留您假设的“无符号字节”范围(在 Java 中不存在):

  int myPort = buffer.get(0) & 0xff; // Might need to change this depending on byte order
  switch(myPort)
      case 0xF1: // Chat service
          break;
      case 0xF2: // Voice service
          break;
      case 0xF3: // Video service
          break;
      case 0xF4: // File transfer service
          break;
      case 0xF5: // Remote login
          break;
  

请注意,由于符号扩展,简单地将字节分配给 int 是行不通的:

  byte val = (byte) 0xb6;  
  int myPort = val;

导致myPort = -74 (0xffffffb6),而

  byte val = (byte) 0xb6;
  int myPort = val & 0xff;

结果为@​​987654326@。


请参阅Why doesn't Java support unsigned ints?,了解有关 Java 中不存在无符号数据类型的一些良好背景信息

【讨论】:

我想我学到了一些新东西。抱歉,我是一名 C/C++ 程序员,所以我习惯于使用无符号字节之类的东西。我不知道它在java中不存在。 这是 Java 的设计决策之一,即使是长期的 Java 程序员也会感到头疼:)【参考方案2】:

您是对的:Java“字节”是介于 -127 和 127 之间的有符号数。

解决方案只是转换为“short”或“int”。

示例:

int myPort = buffer.get(0); // Might need to change this depending on byte order
    switch(myPort)
        case 0xF1: // Chat service
            break;
        case 0xF2: // Voice service
            break;
        case 0xF3: // Video service
            break;
        case 0xF4: // File transfer service
            break;
        case 0xF5: // Remote login
            break;
    

如果您希望将“myPort”保留为“字节”,则只需在 switch 语句中转换为 int:

示例:

byte myPort = buffer.get(0); // Might need to change this depending on byte order
    switch(0xff & (int)myPort)
        case 0xF1: // Chat service
            break;
        ...

无论哪种方式,BITS 都是相同的:导致编译错误的是它们的含义。

【讨论】:

您不必用(myPort & 0x00FF) 屏蔽myPort 以避免符号扩展吗? 不,我不需要屏蔽 myPort,因为我只通过网络发送最低有效字节。我假设我的程序中的高字节是 0xFF。它是一个服务器,它根据最少字节请求建立连接,然后将客户端通道套接字更改为绑定到 (0xFF00 | myPort)。我想尽可能少地通过网络发送。 @Mr.Student 问题是javas字节是有符号的,所以最高有效位被解释为有符号位。在 java 中将有符号字节转换为 int 将“扩展”符号。所有位设置的字节将被转换为 0xffffffff 而不是 0x000000ff。

以上是关于Java中带有十六进制的字节的主要内容,如果未能解决你的问题,请参考以下文章

Java将字节数组转换为十六进制字节数组[重复]

Java打印四字节十六进制数

C# 和 Java 中的十六进制到字节数组给出不同的结果

java byte为何范围是-128~127

Java2

将十六进制字节转换为实际字节[重复]