HOWTO · Java
Java 中的異或運算子
使用 Java 的 ^ 運算子處理布林值與整數異或,並瞭解已驗證的範例和常見陷阱。
本頁內容
在 Java 中,^ 是 XOR(互斥或)運算子。當恰好一個條件應為真時,用它處理 boolean 值;需要按位異或時,用它處理整數。它不是冪次運算子:Java 沒有 ** 運算子。Java Language Specification 定義了這兩種 ^ 形式。
條件請選用布林形式,位元或遮罩請選用整數形式。此運算子可用於目前的 Java 版本;範例已在 OpenJDK 17.0.20.1 執行,準備工作則參考目前 JDK 26 的發行資訊。
將 XOR 用於布林值
對兩個布林運算元而言,只有運算元不同時 XOR 才是 true。真值表很簡單:
| 左側 | 右側 | left ^ right |
|---|---|---|
false |
false |
false |
false |
true |
true |
true |
false |
true |
true |
true |
false |
與 && 和 || 不同,^ 會評估兩個運算元。不要用它取代 value != null && value.isReady() 這類短路保護:方法呼叫仍會執行。只有在同時評估兩個布林運算式是安全的,而且規則是「恰好一個」時才使用它。
這個已驗證的範例同時展示布林 XOR 與整數 XOR:
public class BooleanAndIntegerXor {
public static void main(String[] args) {
System.out.println(true ^ false);
System.out.println(true ^ true);
System.out.println(0b1100 ^ 0b1010);
}
}
輸出:
true
false
6
前兩行說明布林規則。對整數而言,0b1100 ^ 0b1010 產生 0b0110,即十進位 6:只有輸入位元不同的位置,結果位元才是 1。
將 XOR 用於整數與遮罩
按位元形式接受 byte、short、char、int 和 long 等整數基本型別。Java 會在運算前套用二元數值提升,因此含有較小整數型別的運算式通常會得到 int 結果。float 與 double 不能作為 XOR 運算元。只有目標型別確實需要時才轉型;轉型可能捨棄位元。
XOR 可用於切換選定的位元。若 flags 是整數且 mask 標示要變更的位元,flags ^ mask 會剛好反轉那些位元。再次套用同一個遮罩會還原原始位元,因為 x ^ y ^ y 等於 x。此可逆性適合受控的位元操作,但不能取代更清楚的應用程式邏輯。
找出沒有配對的一個值
當其他每個值都剛好出現兩次時,整數 XOR 的簡潔用途是找出沒有配對的值。相等的值會互相抵消,因為 x ^ x 是 0,而 0 ^ x 是 x。
public class UniqueNumberXor {
public static void main(String[] args) {
int unique = 0;
for (int value : new int[] {4, 9, 4}) {
unique ^= value;
}
System.out.println(unique);
}
}
輸出:
9
這是對邊界條件敏感的技巧,不是通用的「尋找唯一數字」演算法。它只在有一個值未配對、其他所有值都剛好出現兩次時有效。例如,若另一個值出現三次,它便無法找出唯一值。當出現規則不同,或還需要頻率資訊時,請選擇計數方法。
適用時優先選擇清楚的替代方案
比較兩個布林值是否不等時,請使用 !=;它可能比 ^ 更直接表達意圖。使用 & 1 檢查整數是奇數還是偶數:奇偶性運算是 AND,不是 XOR。雖然用 XOR 交換兩個變數是廣為人知的技巧,但在 Java 中,暫存變數或一般指派更清楚,也能避免別名錯誤。
關鍵差異很簡單:對 boolean 值而言,^ 表示互斥或;對整數而言,它表示按位 XOR。檢查運算元型別,記住兩個布林側都會被評估,並在依賴重複值抵消之前說明資料假設。