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中带有十六进制的字节的主要内容,如果未能解决你的问题,请参考以下文章