前言
位運算是底層開發、效能優化、權限掩碼、哈希算法的基礎。本文系統講解 Java 位運算符、移位運算符規則、補碼轉換與常見實戰場景。
1. 位運算符
| 運算符 | 名稱 | 規則 | 範例 (二進制) |
| & | 按位與 | 同為 1 結果 1 | 1010 & 1100 = 1000 |
| | | 按位或 | 有一個 1 結果 1 | 1010 | 1100 = 1110 |
| ^ | 按位異或 | 相異為 1 | 1010 ^ 1100 = 0110 |
| ~ | 按位取反 | 0↔1 翻轉 | ~1010 = ...11110101 (補碼) |
2. 移位運算符
| 運算符 | 名稱 | 規則 | 備註 |
| << | 左移 | 低位補 0,高位丟棄 | 等價 ×2ⁿ (無溢出時) |
| >> | 算術右移 | 高位補符號位 | 保持正負號,等價 ÷2ⁿ |
| >>> | 邏輯右移 | 高位補 0 | 無符號右移,負數變大正數 |
3. 補碼與 ~ 運算實例
int a = 5; // 0000...0101
int b = ~a; // 1111...1010 = -6
// 手算步驟:
// 1. 原碼: 0000 0101
// 2. 反碼: 1111 1010
// 3. 補碼: 1111 1010 (負數反碼+1)
// 4. 最高位 1 表負數,數值位 1111010 = 122 → -128+122 = -6
4. 實戰技巧
權限掩碼
int READ = 1 << 0; // 0001
int WRITE = 1 << 1; // 0010
int EXEC = 1 << 2; // 0100
int perm = READ | WRITE; // 0011
boolean canRead = (perm & READ) != 0; // true
boolean canExec = (perm & EXEC) != 0; // false
perm |= EXEC; // 添加執行權
perm &= ~WRITE; // 移除寫入權
快速乘除 2 的冪次
int x = 12;
int mul4 = x << 2; // 48
int div4 = x >> 2; // 3 (保留符號)
int div4u = x >>> 2; // 3 (無符號)
判斷奇偶 / 絕對值 / 交換變數
boolean even = (n & 1) == 0;
int abs = (n ^ (n >> 31)) - (n >> 31); // 無分支絕對值
// 交換 a,b (無臨時變數)
a ^= b; b ^= a; a ^= b;
HashMap 索引計算 (JDK 8)
// (n - 1) & hash 等價於 hash % n (n 為 2 的冪次)
int index = (table.length - 1) & (key.hashCode() ^ (key.hashCode() >>> 16));
5. 注意事項
- 移位量只取低 5 位 (int) 或低 6 位 (long),即
shift & 0x1F / shift & 0x3F。
>>> 無對應的 <<<,因左移無符號位問題。
- 位運算優先級低於比較運算,建議加括號:
if ((flags & MASK) != 0)。
- byte/short/char 參與運算會自動提升為 int,結果需強轉。