Java 提供 7 種位運算符:~ & | ^ << >> >>>,直接操作二進制位,常用於權限掩碼、哈希算法、加密、網絡協議解析、高性能數學運算。本文通過圖解補碼原理、逐位演示、實戰代碼,徹底搞懂位運算。
Java 整型為有符號,負數以 正值補碼 存儲:
1000...0101);1111...1010);1111...1011) —— 這才是內存中真實存儲形式。驗證:Integer.toBinaryString(-5) 輸出 32 位全 1 結尾 1011。
| 運算符 | 名稱 | 規則 | 示例 (5 & 6) | 結果 |
|---|---|---|---|---|
~ | 按位取反 | 0↔1 | ~5 → 111...1010 | -6 |
& | 按位與 | 同為1得1 | 0101 & 0110 = 0100 | 4 |
| | 按位或 | 有1得1 | 0101 | 0110 = 0111 | 7 |
^ | 按位異或 | 異為1,同為0 | 0101 ^ 0110 = 0011 | 3 |
<< | 左移 | 低位補0,高位丟棄 | 5 << 1 = 1010 | 10 (×2) |
>> | 算術右移 | 高位補符號位 | -5 >> 1 = 111...1101 | -3 (÷2 向下取整) |
>>> | 無符號右移 | 高位補0 | -5 >>> 1 = 011...1101 | 2147483645 (大正數) |
// 奇偶
boolean even = (n & 1) == 0;
// 絕對值 (不含 Integer.MIN_VALUE)
int abs = (n ^ (n >> 31)) - (n >> 31);
// 無臨時變量交換
a ^= b; b ^= a; a ^= b;
int READ = 1 << 0; // 0001
int WRITE = 1 << 1; // 0010
int EXEC = 1 << 2; // 0100
int userPerm = READ | WRITE; // 0011
boolean canRead = (userPerm & READ) != 0;
userPerm |= EXEC; // 添加執行權限
userPerm &= ~WRITE; // 移除寫權限
// 是否為 2 的冪次
boolean isPowerOfTwo = (n > 0) && ((n & (n - 1)) == 0);
// 取模 2^n (n 為正整數)
int mod = x & ((1 << n) - 1); // 等價 x % (1<<n) 但更快
x << 3 // x * 8
x >> 2 // x / 4 (負數向下取整)
x >>> 1 // 無符號除 2
int max = a ^ ((a ^ b) & -(a < b)); // 利用符號位擴展
// 或
int diff = a - b;
int sign = (diff >> 31) & 1; // 1 表示 a
int 只看低 5 位 (mod 32),long 看低 6 位 (mod 64)。5 << 32 == 5;>>> 會將負數變為巨大正數,非邏輯除法場景慎用;Integer.MIN_VALUE 絕對值溢出,Math.abs(-2147483648) == -2147483648;&& || !。位運算是通往底層優化的捷徑。掌握 補碼存儲、七大運算符規則、移位乘除、掩碼提取,配合 Integer.toBinaryString 調試,即可在權限系統、哈希分片、網絡協議、算法競賽中游刃有餘。記住:可讀性優先,必要時註釋位運算意圖。