标签:
在面试中,经常会问到“如何不用中间变量交换两个变量值”。
看看下面这个代码输出是什么:
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
这里并没有按照我们想象中的顺序:
而是这样的顺序:
让我们为汇编对应进行一下注释:
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,不易读且难以维护。
标签:
原文地址:http://www.cnblogs.com/tangyouhua/p/4198905.html