想定
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.
Java言語仕様- 15.26.2複合代入演算子 から。
E1 op= E2
という形式の複合代入式はE1 = (T)((E1) op (E2))
と同等です。ここで、T
はE1
のタイプですが、E1
は1回だけ評価されます。
したがって、a &= b;
はa = a & b;
と同等です。
(一部の使用法では、型キャストは結果に違いをもたらしますが、この1つではb
はboolean
でなければならず、型キャストは何もしません。)
また、レコードの場合、a &&= b;
は有効なJavaではありません。 &&=
演算子はありません。
実際には、a = a & b;
とa = a && b;
にはほとんど違いがありません。 b
が変数または定数の場合、結果は両方のバージョンで同じになります。 b
の評価に副作用が生じる可能性がある場合にのみ、意味の違いがあります。すなわち、それが重要な部分式である場合。
パフォーマンスの面では、トレードオフは、b
を評価するコストと、a
の値のテストおよびブランチのコストと、a
への不要な割り当てを回避する潜在的な節約の間です。分析は簡単ではありませんが、b
の計算コストが重要でない限り、2つのバージョン間の潜在的なパフォーマンスの違いは、考慮する価値がないほど小さい可能性があります。
JLSの15.22.2 を参照してください。ブールオペランドの場合、&
演算子はビット単位ではなくブール値です。ブールオペランドの&&
と&
の唯一の違いは、&&
の場合、短絡していることです(つまり、第1オペランドがfalseと評価された場合、第2オペランドは評価されません)。
したがって、あなたの場合、b
がプリミティブの場合、a = a && b
、a = a & b
、およびa &= b
はすべて同じことを行います。
最後の1つです:
a = a & b;
ブール値を使用して、b()が既にfalseである場合に呼び出しを避けたいという状況を見つけました。
これは私のために働いた:
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 &= b
はa = a & b
と同じです。