移位運算符僅適用於整數類型 (int, long, short, char, byte)。操作前,short/char/byte 自動提升為 int;long 保持 long。移位位數取右操作數低位:int 取低 5 位 (模 32),long 取低 6 位 (模 64),防止過度移位。
| 運算符 | 名稱 | 規則 | 高位補充 | 等效數學運算 |
|---|---|---|---|---|
<< | 左移 | 向左移動 n 位,低位補 0 | 低位補 0 | × 2ⁿ (無溢出時) |
>> | 算術右移 (有符號) | 向右移動 n 位 | 符號位擴展:正補 0,負補 1 | ÷ 2ⁿ (向負無窮取整) |
>>> | 邏輯右移 (無符號) | 向右移動 n 位 | 無符號擴展:始終補 0 | 無符號除以 2ⁿ |
int n = -1; // 0xFFFFFFFF
n >> 1 // 0xFFFFFFFF (仍為 -1,符號位擴展)
n >>> 1 // 0x7FFFFFFF (2147483647,高位補 0)
byte/short 進行 >>> 的陷阱 (Java 1.0/1.1 尤顯著)byte b = -1; // 0xFF
b >>> 1; // 編譯時提升為 int (0xFFFFFFFF) → 邏輯右移 → 0x7FFFFFFF → 隱式收窄為 byte → 0xFF (-1) ❌
// 期望 0x7F (127) 但得到 -1
// 修正:(b & 0xFF) >>> 1 → 127 ✅
x <<= n ≡ x = x << n
x >>= n ≡ x = x >> n
x >>>= n ≡ x = x >>> n
下方代碼輸出 int 和 long 的二進制表示,驗證移位、按位與、或、異或、取反效果:
public class BitManipulation {
public static void main(String[] args) {
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
pBinInt("-1", -1);
pBinInt("+1", +1);
pBinInt("MAX_INT", Integer.MAX_VALUE); // 0x7FFFFFFF
pBinInt("MIN_INT", Integer.MIN_VALUE); // 0x80000000
pBinInt("i", i);
pBinInt("~i", ~i);
pBinInt("-i", -i);
pBinInt("j", j);
pBinInt("i & j", i & j);
pBinInt("i | j", i | j);
pBinInt("i ^ j", i ^ j);
pBinInt("i << 5", i << 5);
pBinInt("i >> 5", i >> 5);
pBinInt("(~i) >> 5", (~i) >> 5);
pBinInt("i >>> 5", i >>> 5);
pBinInt("(~i) >>> 5", (~i) >>> 5);
// long 版同理,調用 pBinLong
}
static void pBinInt(String label, int val) {
System.out.printf("%-12s int: %-12d binary: ", label, val);
for (int b = 31; b >= 0; b--) System.out.print(((val >>> b) & 1) == 1 ? '1' : '0');
System.out.println();
}
static void pBinLong(String label, long val) {
System.out.printf("%-12s long: %-22d binary: ", label, val);
for (int b = 63; b >= 0; b--) System.out.print(((val >>> b) & 1) == 1 ? '1' : '0');
System.out.println();
}
}
-1 int: -1 binary: 11111111111111111111111111111111
+1 int: 1 binary: 00000000000000000000000000000001
MAX_INT int: 2147483647 binary: 01111111111111111111111111111111
MIN_INT int: -2147483648 binary: 10000000000000000000000000000000
i int: 59081716 binary: 00000011100001011000001111110100
~i int: -59081717 binary: 11111100011110100111110000001011
-i int: -59081716 binary: 11111100011110100111110000001100
i << 5 int: 1890614912 binary: 01110000101100000111111010000000
i >> 5 int: 1846303 binary: 00000000000111000010110000011111
i >>> 5 int: 1846303 binary: 00000000000111000010110000011111 (正數算術/邏輯右移同)
(~i) >> 5 int: -1846304 binary: 11111111111000111101001111100000 (負數算術右移補 1)
(~i) >>> 5 int: 132371424 binary: 00000111111000111101001111100000 (邏輯右移補 0)
~i (按位取反) 等價於 -i - 1 (補碼定義)-i = ~i + 1 (補碼求相反數)>> 和 >>> 結果相同;負數截然不同>>>** 處理位掩碼、哈希、序列化等無符號邏輯。byte/short 直接用 >>>**,先 & 0xFF 或 & 0xFFFF 擴展為 int 再移位。i << 33 等價 i << 1 (33 % 32 = 1);long 模 64。x * 2 → x << 1,代碼可讀性優先。