Java中的a^=b^=a^=b似乎是错误的

Java中的a^=b^=a^=b似乎是错误的,java,Java,我使用a^b^=a^=b交换a和b。然而,该程序的输出是 public class Main { public static void main(String[] args) { int a,b,c,d; a=1;b=2; a^=b^=a^=b; System.out.println(a+" "+b); c=1;d=2; c^=d; d^=c; c^=d

我使用a^b^=a^=b交换a和b。然而,该程序的输出是

public class Main
{
    public static void main(String[] args)
    {
        int a,b,c,d;
        a=1;b=2;
        a^=b^=a^=b;
        System.out.println(a+" "+b);
        c=1;d=2;
        c^=d;
        d^=c;
        c^=d;
        System.out.println(c+" "+d);
    }
}
我是Java的新手,我不知道为什么a是0。这是我的java运行时环境的一个bug吗?或者Java中有一些特别的东西我不知道?这里是java版本

0 1
2 1

抱歉,这是我关于堆栈溢出的第一个问题。。。如果我忘了一些规则,请告诉我,谢谢。

让我们一起简化一下

java version "1.7.0_65"
OpenJDK Runtime Environment (fedora-2.5.2.5.fc20-x86_64 u65-b17)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)
就是说

int a = 1;
int b = 2;
a ^= (b ^= (a ^= b));
System.out.println(a + " " + b);

您的代码假设我们在a^=(b^=(a^=b)之前处理a^=(b^=(a^=b)),但这是错误的。我真的不知道它在哪里起作用。但正如所指出的,不要在家里尝试这一点。

确保查看操作顺序。这可能就是正在发生的事情:

int a = 1;
int b = 2;
int a_tmp = a;
a = a_tmp ^ (b ^= (a ^= b));
System.out.println(a + " " + b);
从右向左工作:0001^0010^0001^0010在前两个最右边 0001 ^ 0010 = 0011. 现在继续向左移动用下一个元素0010^0011=0001获取答案现在再向左移动一次。0001^0001=0000所以a=0000或0。
现在用b表达式:
0010^0001^0010现在从右向左做同样的事情。0001^0010=0011现在向左移动0010^0011=0001,使b=0001或1。所以当你打印a=0000或0,b=0001或1时。这是按位异或运算。请务必仔细查看运算顺序。

第三次编写时,您的编写方式有所不同。我的建议是什么?不要这样写代码。这是一个模糊代码赢家。你的目标应该是写得尽可能清楚。我知道这不是一个好的编码方式,但我想知道当我使用a^=b^=a^=b时发生了什么。我不认为一个好的程序员也会这么做。从编译器的角度来看,这是完全“合法”的代码,但我有40年的编程经验,10年的Java编程经验,我不能告诉你这意味着什么。不要这样做。我认为这个例子的目的是为了证明这样复杂的表达式可能会让你头疼。是的,任何带有多个赋值的语句充其量都是危险的。“运算符等于”运算符是双重危险的。你的解释是错误的。通过输入0001^0010^0001^0010作为要计算的表达式,假设变量的值尚未更改。但实际上它是一个^0010 ^0001 ^0010。因为在第一个异或求值后0001^0010也会改变a。因此,语句中的第一个变量不再是0001,而是0011。OP实际上是正确的,期望值为2和1(根据规范)。稍后我会给出一个答案,解释为什么结果是0和1。
true ^ true = false  
true ^ false = true 
false ^ true = true 
false ^ false = false

a^=b^=a^=b;