一个简单的Java代码返回一些意想不到的结果



下面最简单的Java代码返回一些意外的输出。让我们看看。

package interchange;
final public class Main
{
    public static void main(String[] args)
    {
        int x = 15;
        int y = 20;
        x^=y^=x^=y;
        System.out.println("x = " + x + "; y = " + y);
    }
}

上面的代码在控制台上显示以下输出:

x = 0; y = 15

如何?

根据运算符的优先级,可以这样重写

x^=y; // 15 ^ 20 = 27, x = 27
y^=27; // 20 ^ 27 = 15, y = 15
x^=15; // 15 ^ 15 = 0, x = 0

您基本上执行x XOR x(因为您对相同的操作数(y)应用了两次xor操作),结果为0。

让我们一步一步地计算你的表达式,在你的例子中,我们必须从右向左执行,以遵循优先级:

     x^=y^=x^=y; 
<=>  y^x^y^x 
<=> (y^y) ^ (x^x) 
<=> (0) ^ (0) 
<=>  0

XOR的操作规则为1 XOR 1 = 0和1 XOR 0 = 1和0 XOR 0 = 0

如果你认为^=是权力。

15 in binary = 01111

异或对出现在其中一个操作数中的每个位返回true,但不是两个操作数都返回true。通过一个更简单的例子可能会有所帮助:

x = 1001
y = 1110
x ^= y => 0111
y ^= x ^= y => 1001
x ^= y ^= x ^= y = 0000

注意:

x <=> y ^= x ^= y

这意味着你最终要执行:

x ^= x

…根据异或的定义,该值必须为零。

为完整起见,下面是使用xy提供的值的操作:

x = 0000 1111
y = 0001 1011
x ^= y = 0001 0100
y ^= x ^= y => 0000 1111
x ^= y ^= x ^= y => 0000 0000

我没有一个实际的答案,但我不认为优先级是问题。添加括号来澄清,同样的事情发生:

//   3   2   1
   x^=(y^=(x^=y));

我希望从这里得到的等价于:

x^=y; //1: xor x with y, update x, return the new x;
y^=x; //2: xor y with (result of 1), update y, return the new y;
x^=y; //3: xor x with (result of 2), update x, return the new x;

我认为实际情况是使用了初始值,这实际上意味着:

x0 = x;
y0 = y;
x = x0^y0^x0^y0; //0
y = y0^x0^y0;    //15

问题是,我不确定在语言规范中我可以找到这个。最接近的是:

15.7.2

操作前求操作数

Java编程语言还保证操作符的每个操作数(除了条件运算符&&、||和?:)似乎得到了充分的评估在操作本身的任何部分执行之前。

最新更新