web-dev-qa-db-ja.com

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.
129
pakore

Java言語仕様- 15.26.2複合代入演算子 から。

E1 op= E2という形式の複合代入式はE1 = (T)((E1) op (E2))と同等です。ここで、TE1のタイプですが、E1は1回だけ評価されます。

したがって、a &= b;a = a & b;と同等です。

(一部の使用法では、型キャストは結果に違いをもたらしますが、この1つではbbooleanでなければならず、型キャストは何もしません。)

また、レコードの場合、a &&= b;は有効なJavaではありません。 &&=演算子はありません。


実際には、a = a & b;a = a && b;にはほとんど違いがありません。 bが変数または定数の場合、結果は両方のバージョンで同じになります。 bの評価に副作用が生じる可能性がある場合にのみ、意味の違いがあります。すなわち、それが重要な部分式である場合。

パフォーマンスの面では、トレードオフは、bを評価するコストと、aの値のテストおよびブランチのコストと、aへの不要な割り当てを回避する潜在的な節約の間です。分析は簡単ではありませんが、bの計算コストが重要でない限り、2つのバージョン間の潜在的なパフォーマンスの違いは、考慮する価値がないほど小さい可能性があります。

136
Stephen C

JLSの15.22.2 を参照してください。ブールオペランドの場合、&演算子はビット単位ではなくブール値です。ブールオペランドの&&&の唯一の違いは、&&の場合、短絡していることです(つまり、第1オペランドがfalseと評価された場合、第2オペランドは評価されません)。

したがって、あなたの場合、bがプリミティブの場合、a = a && ba = a & b、およびa &= bはすべて同じことを行います。

48
stew

最後の1つです:

a = a & b;
20

ブール値を使用して、b()が既にfalseである場合に呼び出しを避けたいという状況を見つけました。

これは私のために働いた:

a &= a && b()
0
Daniel Testa

これをテストする簡単な方法を次に示します。

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と同じです。

0
user7291698