mkdreamer 2021-12-14 17:25 采纳率: 80%
浏览 39
已结题

在学习java位运算符的时候,遇到了关于使用^交换数据的值

设有两个整数变量x与y
x ^= y;
y ^= x;
x ^= y;
能成功交换x与y的值。

为什么将上面的式子改成
x ^= y ^= x ^= y
不能成功交换?

甚至
y ^= x ^= y;
x ^= y;
也能实现。

  • 写回答

2条回答 默认 最新

  • 俺不理解 2021-12-14 18:29
    关注

    java的编译规则赋值优化。举个例子

    a = 10;
    a = 20;

    连续的两次赋值,且中间没发现对a的读取,那么java编译器在编译时会将第一个赋值删掉。


    再回到这次的问题:
    b ^= a ^= b; 在编译后的 class文件中,这一行应该是先将a 与 b 做一次 ^=,a的结果再与 b 做一次 ^=
    看下class文件,的确如此:

    img

    img


    现在我们把它们写成一行

    img

    其实可以看到,这个时候编译器已经告诉我们警告(第二个a是灰色)编译器认为这一行代码会被编译成

    img

    我们再来看看此时的 class 文件

    img

    通过编译后的文件,我们可以很清晰的知道为什么 执行完这一行,a = 0、b = 10,那么为什么编译器会这样执行呢?

    这就回到刚开篇的赋值优化问题了, 对于 a ^= b,这对a是一次赋值的过程,也读取了一次a的值,但是 对于 a^= (b ^= a ^= b) 的外层 a ^= 操作来说,java编译器认为后边括号里的内容是一次赋值,且与a无关,所以 内部的一次 ^= 操作被编译器优化掉了。

    事实上,a^= (b ^= a ^= b) 会被优化成如下代码:

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月22日
  • 已采纳回答 12月14日
  • 创建了问题 12月14日

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值