java中无符号short需用(short)x & 0xffff提取低16位并零扩展为0~65535,而非(int)(short)x避免符号扩展;网络字节流中常用b1

Java 中没有真正的无符号类型,但可以通过位运算和类型转换来模拟无符号短整型(unsigned short)的行为。当把一个负的 int 强转为 short 后再当作无符号值解释时,关键不是“强转本身”,而是**如何正确提取其低 16 位并视作 0~65535 范围的数**。
理解底层:负数 int 转 short 的二进制截断
Java 的 int 是 32 位有符号补码,short 是 16 位有符号补码。强制转换 (short) x 会直接截取低 16 位,高位丢弃。例如:
int x = -1; // 32 位补码: 0xFFFFFFFF short s = (short) x; // 截取低 16 位 → 0xFFFF → 值为 -1(有符号) // 但若将其视为 unsigned short,则 0xFFFF = 65535
获取等效的无符号 short 值(0~65535)
将 short 当作无符号处理,标准做法是用 & 0xFFFF 提升为 int,自动完成零扩展:
-
推荐写法:
int unsignedValue = (short) x & 0xFFFF; - 注意顺序:
(short) x先截断,再与0xFFFF按位与,确保高 16 位清零,结果是 0~65535 的正整数 - 不要写
(int)(short) x—— 这会符号扩展,-1 变成 -1(0xFFFFFFFF),不是想要的 65535
常见场景示例
比如读取网络字节流或文件中按大端存储的 unsigned short:
- 从 byte[] 中读两个字节:
int b1 = bytes[i] & 0xFF; int b2 = bytes[i+1] & 0xFF; - 组合为 unsigned short:
int value = (b1 (大端) - 若你已有
int raw(可能为负),且确认它代表一个被错误解释为有符号的 unsigned short,则用:int us = raw & 0xFFFF;(更简洁,无需先转 short)
注意事项
Java 里所有算术运算默认以 int 进行,short 总是隐式提升。因此“无符号 short”本质上只是对 16 位数据的一种解释方式,实际存储和运算仍用 int 更安全、清晰。
不复杂但容易忽略:核心就一条——用 & 0xFFFF 来屏蔽高位,获得逻辑上的无符号 16 位值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











