Why is “a^=b^=a^=b;” different from “a^=b; b^=a; a^=b;”?

本文探讨了使用异或(XOR)操作符在Java中不借助第三个变量实现两个整数变量交换的方法。通过对比两种不同实现方式的结果,揭示了Java语言规范中关于复合赋值表达式的求值顺序,解释了为何不同的代码结构会产生意料之外的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I tried some code to swap two integers in Java without using a 3rd variable, using XOR.

Here are the two swap functions I tried:

package lang.numeric;

public class SwapVarsDemo {

    public static void main(String[] args) {
        int a = 2984;
        int b = 87593;
        swapDemo1(a,b);
        swapDemo2(a,b);
    }

    private static void swapDemo1(int a, int b) {
        a^=b^=a^=b;
        System.out.println("After swap: "+a+","+b);
    }

    private static void swapDemo2(int a, int b) {
        a^=b;
        b^=a;
        a^=b;
        System.out.println("After swap: "+a+","+b);
    }

}

The output produced by this code was this:

After swap: 0,2984
After swap: 87593,2984

I am curious to know, why is this statement:

        a^=b^=a^=b;

different from this one?

        a^=b;
        b^=a;
        a^=b;


回答如下:

he issue is the order of evaluation:

See JLS section 15.26.2

First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.

Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

So your expression does:

a^=b^=a^=b;

  1. evaluate a
  2. evaluate b^=a^=b
  3. xor the two (so the a in step one does not have ^=b applied to it yet)
  4. store the result in a

In other words, your expression is equivalent to the following java code:

    int a1 = a;
    int b2 = b;
    int a3 = a;
    a = a3 ^ b;
    b = b2 ^ a;
    a = a1 ^ b;

You can see that from the disassembled version of your method:

  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  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值