繁体   English   中英

一个简单的Java代码会返回一些意外结果

[英]A simple Java code returns some unexpected result

以下最简单的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进行x XOR x (因为您对相同的操作数(y)两次应用了异或运算),结果为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二进制= 01111 20二进制= 10100

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

x = 1001
y = 1110

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

注意:

x <=> y ^= x ^= y

这意味着您最终将执行:

x ^= x

...根据XOR的定义,必须为零。

为了完整起见,以下是使用提供的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编程语言还保证在执行操作本身的任何部分之前,对运算符的每个操作数(条件运算符&&,||和?:除外)都应进行完全评估。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM