假设
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.
答案 0 :(得分:133)
来自Java语言规范 - 15.26.2 Compound Assignment Operators。
E1 op= E2
形式的复合赋值表达式等同于E1 = (T)((E1) op (E2))
,其中T
是E1
的类型,但E1
除外仅评估一次。
因此a &= b;
相当于a = a & b;
。
(在某些用法中,类型转换会对结果产生影响,但在此b
中,boolean
必须为a &&= b;
且类型转换不执行任何操作。)
并且,对于记录,&&=
不是有效的Java。没有a = a & b;
运营商。
在实践中,a = a && b;
和b
之间几乎没有区别。如果b
是变量或常量,则两个版本的结果都相同。当b
的评估可能产生副作用时,只有语义上的差异;即,当它是一个非平凡的子表达式时。
在绩效方面,权衡取决于评估a
的成本,以及a
的测试和分支的成本,以及避免不必要的潜在节省转让给b
。分析不是直截了当的,但除非计算{{1}}的成本非常重要,否则两个版本之间的潜在性能差异可能太小而不值得考虑。
答案 1 :(得分:47)
见15.22.2 of the JLS。对于布尔操作数,&
运算符是布尔值,而不是按位。 &&
和&
对于布尔操作数的唯一区别是,对于&&
,它被短路(意味着如果第一个操作数的计算结果为false,则不评估第二个操作数)。 / p>
因此,在您的情况下,如果b
是基元,a = a && b
,a = a & b
和a &= b
都会做同样的事情。
答案 2 :(得分:20)
这是最后一个:
a = a & b;
答案 3 :(得分:0)
我遇到了一个类似的情况,使用布尔值,我想避免调用b(),如果a已经是假的。
这对我有用:
a &= a && b()
答案 4 :(得分:0)
这是一种简单的测试方法:
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 &= b
与a = a & b
相同。