Java & = 运算符是否应用 & 或 & & ?

假设

boolean a = false;

我想知道如果做:

a &= b;

相当于

a = a && b; //logical AND, a is false hence b is not evaluated.

或者从另一方面来说

a = a & b; //Bitwise AND. Both a and b are evaluated.
145781 次浏览

这是最后一个:

a = a & b;

来自 Java 语言规范 -15.26.2复合式指配营办商

E1 op= E2形式的复合赋值表达式等价于 E1 = (T)((E1) op (E2)),其中 TE1的类型,除了 E1只计算一次。

所以 a &= b;等于 a = a & b;

(在某些用法中,类型强制转换会对结果产生影响,但在这种用法中,b必须是 boolean,而类型强制转换什么也不做。)

而且,根据记录,a &&= b;不是有效的 Java,没有 &&=操作符。


在实际应用中,a = a & b;a = a && b;之间的语义差异很小。(如果 b是一个变量或常量,那么两个版本的结果将是相同的。当 b是一个具有副作用的子表达式时,只有语义上的区别。在 &的情况下,副作用总是发生。在 &&的情况下,它取决于 a的值。)

在性能方面,取舍是在评估 b的成本和 a值的测试和分支的成本之间,以及避免向 a进行不必要的分配的潜在节约。分析并不简单,但是除非计算 b的成本非常高,否则两个版本之间的性能差异太小,不值得考虑。

JLS 的15.22.2。对于布尔操作数,&运算符是布尔运算符,而不是按位运算。对于布尔操作数,&&&之间的唯一区别是,对于 &&,它是短路的(意味着如果第一个操作数的计算结果为 false,则不计算第二个操作数)。

所以在您的例子中,如果 b是一个基元,那么 a = a && ba = a & ba &= b都做同样的事情。

我遇到过类似的情况,使用布尔值时,我想避免在 a 已经为 false 时调用 b ()。

这对我很有效:

a &= a && b()

这里有一个简单的测试方法:

public class OperatorTest {
public static void main(String[] args) {
boolean a = false;
a &= b();
}


private static boolean b() {
System.out.println("b() was called");
return true;
}
}

输出是 b() was called,因此计算右边的操作数。

因此,正如其他人已经提到的,a &= ba = a & b是一样的。