假设
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.
这是最后一个:
a = a & b;
来自 Java 语言规范 -15.26.2复合式指配营办商。
E1 op= E2形式的复合赋值表达式等价于 E1 = (T)((E1) op (E2)),其中 T是 E1的类型,除了 E1只计算一次。
E1 op= E2
E1 = (T)((E1) op (E2))
T
E1
所以 a &= b;等于 a = a & b;。
(在某些用法中,类型强制转换会对结果产生影响,但在这种用法中,b必须是 boolean,而类型强制转换什么也不做。)
b
boolean
而且,根据记录,a &&= b;不是有效的 Java,没有 &&=操作符。
a &&= b;
&&=
在实际应用中,a = a & b;和 a = a && b;之间的语义差异很小。(如果 b是一个变量或常量,那么两个版本的结果将是相同的。当 b是一个具有副作用的子表达式时,只有语义上的区别。在 &的情况下,副作用总是发生。在 &&的情况下,它取决于 a的值。)
a = a && b;
&
&&
a
在性能方面,取舍是在评估 b的成本和 a值的测试和分支的成本之间,以及避免向 a进行不必要的分配的潜在节约。分析并不简单,但是除非计算 b的成本非常高,否则两个版本之间的性能差异太小,不值得考虑。
见 JLS 的15.22.2。对于布尔操作数,&运算符是布尔运算符,而不是按位运算。对于布尔操作数,&&和 &之间的唯一区别是,对于 &&,它是短路的(意味着如果第一个操作数的计算结果为 false,则不计算第二个操作数)。
所以在您的例子中,如果 b是一个基元,那么 a = a && b、 a = a & b和 a &= b都做同样的事情。
a = a && b
a = a & b
a &= 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,因此计算右边的操作数。
b() was called
因此,正如其他人已经提到的,a &= b和 a = a & b是一样的。