异或能交换两个整数是因为其可逆性:a ^ b ^ b == a;三步为a=a^b、b=a^b、a=a^b;但不可用于同一变量、浮点数、对象引用及多线程场景,且实际开发中因可读性差和编译器优化而 rarely 推荐。

为什么异或能交换两个整数而不需临时变量
因为 ^ 是可逆的位运算:对同一数连续异或两次,结果不变,即 a ^ b ^ b == a。利用这个性质,三步就能完成交换:a = a ^ b → b = a ^ b → a = a ^ b,中间没有信息丢失。
标准三行异或交换写法及注意事项
这是最常见也最容易出错的写法,必须严格按顺序执行:
a = a ^ b;-
b = a ^ b;(此时等价于(a^b) ^ b == a) -
a = a ^ b;(此时等价于(a^b) ^ a == b)
⚠️ 容易踩的坑:不能用在同一个变量上,比如 a = a ^ b ^ a; 这种“一步到位”写法是错的——它不等于交换,而是直接把 a 变成 b,b 没变。
什么情况下绝对不能用异或交换
以下场景会出错或无意义:
立即学习“Java免费学习笔记(深入)”;
- 当
a和b引用的是同一个变量(如swap(arr[i], arr[i])),执行后该值变成0(因为x ^ x == 0) - 涉及浮点数、对象引用、
long(若未用long类型做运算,可能截断) - 在多线程环境下,没有同步机制时,异或交换不是原子操作,无法保证线程安全
- 现代 JVM 对
int交换的优化极好,异或写法反而可能干扰 JIT 编译器的寄存器分配
实际开发中更推荐的做法
除非在嵌入式或极端内存受限场景,否则别用异或交换:
- 可读性差,新人看不懂,维护成本高
- 编译器/解释器早已对普通临时变量交换做了深度优化(甚至可能内联为单条 CPU 指令)
- Java 中真正省空间的场景极少,而
int本身才 4 字节,临时变量开销几乎为零 - 如果真想“不声明新变量”,可以用数组或记录类封装,但那已不属于“异或交换”的范畴了
异或交换是个聪明的小技巧,但聪明不等于实用;它只在特定教学或底层位操作上下文中保持价值。










