Java 移动字节 returns 一个意外的结果

Java shifting bytes returns an unexpected result

我正在尝试将 2 个字节转换为一个短字节。这 2 个字节代表一个无符号短整数,它又代表一个端口。我尝试了多种方法将这些字节转换为 java 上的短字节。然而,我总是无法正确地做到这一点。

这些是我尝试过的方法:

byte a = 0x17;
byte b = 0xCC;

(short)((a << 8) | b);
(short)(((short)a << 8) | b);

结果是0xFFCC,但应该是0x17CC。

在 Java 中进行算术运算的任何值首先被转换为可以覆盖两个操作数的更高类型。如果两个操作数仍然更小,则将其转换为 int

因此,b 首先转换为 int 并变为 0xFFFFFFCC。将它与向左移动 8 位的任何内容进行或运算始终保持掩码 0xFFFFFF00,因此对结果没有影响。将它转换为 short 只会缩小左边的 16 位。

要解决它,请在执行操作之前用 0xFF 显式屏蔽:

(short)(((a&0xFF)<<8)|(b&0xFF))

//试试这个,因为你不能从 int 转换为 byte:

short a = 0x17; short b = 0xCC; System.out.println("r = " + String.format("0x%04X", (short)((a << 8) | b)));

//输出:r = 0x17CC