【问题标题】:Bitwise AND (&) expression in JavaJava 中的按位与 (&) 表达式
【发布时间】:2011-03-21 18:39:32
【问题描述】:

我正在调试其中包含expr1 & expr2 的代码,其中expr1 具有影响expr2 评估结果的副作用。我怀疑expr2expr1 之前被评估,因为JLS 保证&& 的从左到右评估,但不一定是&。我还怀疑评估顺序的变化可能是 HotSpot 执行优化的结果(我们正在运行 Java 6u20)。不知道HotSpot能不能做这样的优化?更好的是,提供任何指向支持或消除怀疑的文档的指针。提前致谢。

编辑:感谢那些建议重写代码,使其既正确又可读 - 你是对的,但我已经这样做了,所以这不是我想要的。不幸的是,很难测试这种变化,这就是我在这里问这个问题的原因。

【问题讨论】:

  • 为什么不把if (A() & B()) 变成boolean a = A(); boolean b = B(); if (a & b) 看看能不能解决问题?
  • 是什么让您认为按位不能保证从左到右?我在规范中可以找到的唯一区别是,对于按位,expr2 保证会被评估,但对于逻辑它会被短路,但在任何一种情况下,它总是 L->R,并且 @ 987654332@ 的操作数将在 expr2 的任何部分之前计算。
  • download-llnw.oracle.com/javase/tutorial/java/nutsandbolts/… 声明除了赋值之外的所有二元运算符都是从左到右计算的。
  • 是否绝对有必要产生副作用?一般来说,这是一个坏主意。 expr1; expr2; expr1Result & expr2Result; 会好很多,并且会避免此类问题。
  • @Joe 只有短路逻辑二元运算符可以(并且必须短路)。即&&|| 做; &|^/!=== 不要。

标签: java bitwise-operators jvm-hotspot short-circuiting


【解决方案1】:

评估顺序在specification中明确定义:

Java 编程语言保证运算符的操作数看起来是按照特定的计算顺序计算的,即从左到右。

如果这改变了结果,HotSpot 优化器不应进行导致 expr2 在 expr1 之前被评估的优化。如果它这样做,那就是一个错误。

还要注意它说:

建议代码不要过度依赖本规范。

您的代码可以更清楚地重写如下:

int a = expr1;
int b = expr2;
int result = a & b;

【讨论】:

    【解决方案2】:

    JLS 第 3 版第 15.7 节从左到右讨论评估顺序,但要求不要非常依赖它(短路的除外)

    【讨论】:

      猜你喜欢
      • 2013-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多