java中可用^交换两个int或long变量,但需满足整型、不同内存位置、三步顺序执行三个前提;其原理基于异或的自反性、恒等性及可交换结合性;同一变量、非整型、biginteger及多线程场景禁用;虽无溢出风险,但无性能优势,工程中推荐临时变量。

Java 中可以用 ^(异或)运算符不借助临时变量交换两个 int 或 long 类型变量的值,但必须满足三个前提:变量类型是整型、两个变量指向不同内存位置、严格按三步顺序执行。
异或交换的正确写法
假设初始值 a = 5,b = 9,交换需分三行写,不可合并或颠倒:
-
a = a ^ b;→ 此时a变为5 ^ 9 = 12 -
b = a ^ b;→ 即12 ^ 9 = 5,b得到原a的值 -
a = a ^ b;→ 即12 ^ 5 = 9,a得到原b的值
为什么它能成立?关键在异或的数学性质
异或具备三个核心性质:
-
自反性:任何数异或自己等于 0,即
x ^ x == 0 -
恒等性:任何数异或 0 等于自身,即
x ^ 0 == x -
可交换与结合:
a ^ b ^ c == c ^ a ^ b,顺序不影响结果
代入推导:设初始 a=x、b=y,三步后:
① a₁ = x ^ y;
② b₂ = a₁ ^ y = (x ^ y) ^ y = x;
③ a₃ = a₁ ^ b₂ = (x ^ y) ^ x = y。
信息未丢失,仅靠位运算完成互换。
哪些情况绝对不能用?
-
同一变量或同一数组元素:如
swap(arr[0], arr[0]),第一步arr[0] = arr[0] ^ arr[0]就变成 0,后续全为 0 -
非整型类型:
float、double、String、Integer(包装类)等不支持^运算 -
BigInteger 或大数场景:该类无
^中缀操作符,也不支持就地修改,必须用临时引用 - 多线程共享变量:三步非原子操作,中间状态可能被其他线程读取,引发竞态
和加减法交换相比有什么优势?
加减法写法 a = a + b; b = a - b; a = a - b 看似简洁,但有硬伤:
- 整数溢出风险:例如
a = Integer.MAX_VALUE、b = 1,第一步就回绕成负数,结果错误 - 异或全程无进位、无符号扩展,只要类型宽度一致(如两个
int),就完全不溢出 - 但注意:异或没性能优势——现代 JVM 对临时变量(如
int temp = a)早已优化到寄存器级,字节码几乎无额外开销
工程实践中,推荐直接用临时变量。异或交换只适合算法题中“禁止额外空间”的限定场景,日常代码中可读性差、易出错、维护成本高,不值得刻意使用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











