首页 > 代码库 > Java随笔:使用异或操作交换变量值的风险
Java随笔:使用异或操作交换变量值的风险
在面试中,经常会问到“如何不用中间变量交换两个变量值”。
看看下面这个代码输出是什么:
int x = 1984;int y = 2001;x^=y^=x^=y;System.out.println("x="+x+";y="+y);
看上去应该很完美的:x=2001;y=1984
实际输出是:x=0;y=1984
问题出在哪里?是的,就是JVM的编译器。
看看实际的汇编:
Code: 0: sipush 1984 3: istore_1 4: sipush 2001 7: istore_2 8: iload_1 9: iload_2 10: iload_1 11: iload_2 12: ixor 13: dup 14: istore_1 15: ixor 16: dup 17: istore_2 18: ixor 19: istore_1 20: getstatic #2
这里并没有按照我们想象中的顺序:
- x^=y
- y^=x^=y
- x^=y^=x^=y
而是这样的顺序:
- x=1984
- y=2001
- temp1=x
- temp2=y
- temp3=x^y
- x=temp3
- y=temp2^temp3
- x=temp1^y
让我们为汇编对应进行一下注释:
Code: 0: sipush 1984 3: istore_1 // x=1984 4: sipush 2001 7: istore_2 // y=2001 8: iload_1 // 堆栈(高到低) 1984 9: iload_2 // 2001, 1984 10: iload_1 // 1984,2001,1984 11: iload_2 // 2001,1984,2001,1984 12: ixor // 2001^1984 ,堆栈(17,2001,1984) 13: dup // temp3=2001^1984=17 14: istore_1 // x=temp3=17 15: ixor // 17^2001,堆栈(1984,,1984) 16: dup // temp3=1984 17: istore_2 // y=1984 18: ixor // 1984^1984,堆栈(0) 19: istore_1 // x=0 20: getstatic #2
也就是说,实际编译器没有按照我们想象的那样,执行x^=y^=x^=y。
总结
单个表达式不要对相同的变量赋值2次,否则无法从混乱中得到预期的结果。
使用异或进行数值交换,容易产生bug,不易读且难以维护。
Java随笔:使用异或操作交换变量值的风险
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。