异或交换整数本质是利用a^a=0、a^0=a及结合律/交换律,严格三步顺序执行可完成交换;但仅适用于同类型基本整数,禁用于浮点数、对象引用、自交换及多线程场景,且因可读性差和优化受限,实际开发不推荐。

Java 中用异或(^)交换两个整数变量,本质是利用其数学性质:**a ^ a = 0,a ^ 0 = a,以及结合律和交换律**。它能在不借助临时变量的前提下完成交换,但仅适用于 基本整数类型(如 int、long),且有明确前提和限制。
适用条件和核心逻辑
必须同时满足以下三点,三步异或才真正等价于交换:
- 两个变量是同一基本整数类型(比如都是
int) - 它们不是同一个内存位置(即不能是
swap(arr[i], arr[i])这种自交换) - 运算严格按顺序执行:先
a = a ^ b,再b = a ^ b,最后a = a ^ b
推导简明版:
- 第一步后:
a变成a ^ b - 第二步:
b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a→b得到原a的值 - 第三步:
a = (a ^ b) ^ a = b ^ (a ^ a) = b ^ 0 = b→a得到原b的值
正确写法示例
以下代码可直接运行,结果为 a = 789012, b = 123456:
立即学习“Java免费学习笔记(深入)”;
int a = 123456; int b = 789012; a = a ^ b; b = a ^ b; // 此时 b 已是原 a a = a ^ b; // 此时 a 已是原 b
哪些情况绝对不能用
-
BigInteger 或 Integer:前者不可变且不支持
^运算符;后者需拆箱装箱,实际仍生成新对象,无法原地交换 - 浮点数(float/double):位模式不满足整数异或的代数推导,结果不可预测
-
同一变量引用:如
int x = 5; x = x ^ x; x = x ^ x; x = x ^ x;,最终是0,不是交换 - 多线程环境:三步操作非原子,无同步时可能被中断,导致中间态暴露或错乱
为什么实际开发中很少推荐
虽然看起来“炫技”又省一个变量,但问题明显:
- 可读性差:新人难理解,维护成本高
- 编译器优化受限:现代 JVM 对临时变量交换优化极好,异或反而可能干扰寄存器分配
- 易出错:顺序写错、类型误用、边界场景(如溢出不报错但逻辑错)都难以排查
- 无实质收益:在绝大多数应用层场景,节省一个
int变量毫无意义
除非在嵌入式、芯片级编程或极端内存受限的底层场景,否则直接用临时变量更稳妥、清晰、可靠。


















