2010-10-11 39 views
106

假设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. 

回答

111

从Java语言规范 - 15.26.2 Compound Assignment Operators

形式E1 op= E2的化合物赋值表达式是等效于E1 = (T)((E1) op (E2)),其中TE1类型,不同之处在于E1只计算一次。

所以a &= b;相当于a = a & b;

(在某些用途中,类型转换,使该结果的差异,但在这一个b必须是boolean和类型,投什么都不做。)


在实践中,有a = a & b;a = a && b;之间的差异很小。如果b是一个变量或一个常数,那么两个版本的结果都是一样的。当b的评估可能有副作用时,只有语义上的差异;即当它是一个不平凡的子表达式时。

在性能方面,权衡是评估b的成本与a价值的测试和分支的成本之间的平衡,以及避免不必要地分配给a的潜在节省。分析并不是直截了当的,但除非计算成本b不重要,否则两个版本之间潜在的性能差异可能太小而不值得考虑。

19

这是最后一个:

a = a & b; 
30

参见15.22.2 of the JLS。对于布尔操作数,&运算符是布尔值,而不是按位。对于布尔操作数,&&&之间的唯一区别是对于&&它是短路的(意思是如果第一个操作数评估为false,则不评估第二个操作数)。

你的情况

所以,如果b是一种原始的,a = a && ba = a & b,并a &= b都做同样的事情。

+1

所以(一&= b;)将于如果b是一个方法调用没有短路?有没有像“&& =”运算符? – is7s 2012-04-25 18:34:20

+1

正确。 b()被调用。没有&& =运算符。 – stew 2012-04-25 18:45:52

+1

看来这不能回答这个问题; OP已经知道短路。 – 2012-11-15 07:58:41

0

我遇到了类似的情况使用布尔值,我想避免调用b()如果a已经是假的。

这为我工作:

a &= a && b() 
+21

为了避免冗余(仍然允许短路),您可以简单地写'a = a && b()'。 – 2012-09-08 09:39:24