标签:
在面试中,经常会问到“如何不用中间变量交换两个变量值”。
看看下面这个代码输出是什么:
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