问题是评估的顺序:
参见JLS第15.26.2节
首先,对左操作数求值以产生一个变量。 如果该评估突然完成,则赋值表达式由于相同的原因而突然完成;右边的操作数不会被评估,并且不会发生赋值。
否则,将保存左侧操作数的值,然后评估右侧操作数。如果该评估突然完成,则赋值表达式由于相同的原因突然完成,并且不会发生赋值。
否则,将左侧变量的保存值和右侧操作数的值用于执行复合赋值运算符指示的二进制运算。如果该操作突然完成,则赋值表达式由于相同的原因而突然完成,并且不会发生赋值。
否则,将二进制运算的结果转换为左侧变量的类型,进行值集转换(第5.1.13节)为适当的标准值集(而不是扩展指数值集),然后将结果转换的结果存储到变量中。
所以你的表情是:
a^=b^=a^=b;
- 评估
a
- 评估
b^=a^=b
- 将两者进行异或运算(因此
a
第一步中的尚未^=b
应用) - 将结果存储在
a
换句话说,您的表达式等效于以下Java代码:
int a1 = a; int b2 = b; int a3 = a; a = a3 ^ b; b = b2 ^ a; a = a1 ^ b;
您可以从方法的反汇编版本中看到这一点:
private static void swapDemo1(int, int); Code: 0: iload_0 1: iload_1 2: iload_0 3: iload_1 4: ixor 5: dup 6: istore_0 7: ixor 8: dup 9: istore_1 10: ixor 11: istore_0



