java对负数位移先取模(int对32、long对64),再执行位移,-1>>-1等价于-1>>31得-1,-1>>>-1等价于-1>>>31得0x7fffffff,负数位移易引发bug,应避免并显式校验。

Java 中对负数进行位移操作时,编译器不会报错,但结果可能和直觉相反——因为 Java 会先对位移量取模(mod),再执行实际位移。
负数位移量会被自动取模
Java 规定:对于 int 类型,位移量只取低 5 位(即对 32 取模);对于 long 类型,只取低 6 位(即对 64 取模)。这意味着位移量 -1、31、63 等在 int 或 long 上可能等效。
1 等价于 <code>1 → <code>1 (因为 -1 的二进制补码低 5 位是 11111 = 31)-
5 >> -2等价于5 >> ( -2 & 0x1F )→5 >> 30 1L 对 long 是 <code>1L → <code>1L
右移负数时注意符号扩展
使用 >>(带符号右移)时,高位补的是符号位。若原数为正,即使位移量很大(如右移 30 位),结果通常为 0;若原数为负,高位补 1,可能得到 -1 或其他负值。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
-8 >> 1→-4(正常带符号右移) -
-8 >> 31→-1(所有位都补 1) -
8 >> 31→0(正数高位补 0)
无符号右移(>>>)对负数也适用,但逻辑不变
>>> 总是高位补 0,不管原数正负。当位移量为负时,仍先取模,再执行无符号右移:
-
-1 >>> -1→-1 >>> 31→0x7FFFFFFF(即 2147483647) -
-1 >>> 31和-1 >>> -1结果相同 - 注意:
-1 >>> 32等价于-1 >>> 0→ 还是 -1(因为 32 % 32 = 0)
实际开发中应避免负数位移
虽然语法合法,但负数位移容易引发隐蔽 bug,可读性差,且不同语言行为不一致(例如 C/C++ 中负数位移是未定义行为)。
- 建议显式校验位移量:
if (n = 32) throw new IllegalArgumentException(); - 用位掩码替代大位移:比如想取高 8 位,用
(x >> 24) & 0xFF比x >> -8清晰安全得多 - IDE 或静态分析工具(如 SpotBugs)通常会警告负数位移操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










