可以将两个short无损打包进一个int:先用&a & 0xFFFF确保无符号位模式,再左移16位与另一short按位或;拆分时分别取高16位和低16位并强转short,避免符号扩展错误。

可以将两个 short(各占16位)无损打包进一个 int(32位),利用位移和按位或操作实现零开销合并与安全拆分。
打包:左移 + 按位或
将第一个 short 直接作为高16位,第二个作为低16位:
- 先将第一个
short转为int并左移16位:(a & 0xFFFF) (<code>& 0xFFFF确保符号位不扩展) - 将第二个
short转为int并保留低16位:b & 0xFFFF - 两者按位或:
packed = ((a & 0xFFFF)
拆包:右移 + 掩码提取
从 int 中还原两个 short 值:
- 高位(原第一个
short):(packed >> 16) & 0xFFFF,再强制转short即可 - 低位(原第二个
short):packed & 0xFFFF,同样转short - 注意:Java中
short是有符号的,但打包时用& 0xFFFF保持原始位模式,还原后类型转换会自动处理符号位
关键细节:避免符号扩展陷阱
直接对负数 short 进行算术右移或赋值会触发符号扩展(如 (short)-1 → 0xFFFF,但若直接转 int 可能变成 0xFFFFFFFF):
立即学习“Java免费学习笔记(深入)”;
- 打包前务必用
& 0xFFFF将short视为无符号16位整数,得到正确位模式 - 拆包后用
(short)强制转换,JVM 会按补码规则正确还原有符号值 - 例如:
short a = -1; // 0xFFFF→ 打包后高位为0xFFFF0000;拆出再转short仍是-1
完整示例代码
(可直接运行验证)
short a = -12345, b = 54321; int packed = ((a & 0xFFFF) << 16) | (b & 0xFFFF); short restoredA = (short) ((packed >> 16) & 0xFFFF); short restoredB = (short) (packed & 0xFFFF); System.out.println(a == restoredA && b == restoredB); // true


















