Java&=演算子は&または&&を適用しますか?


139

想定

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.

回答:


146

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

フォームの化合物代入式は、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副作用がある部分式の場合、意味上の違いのみがあります。この&場合、副作用は常に発生します。&&の値に応じて発生する場合a。)

パフォーマンスの面では、の評価bコストと、の値のテストと分岐のコストa、およびへの不要な割り当てを回避することによる潜在的な節約との間のトレードオフですa。分析は簡単ではありませんが、計算のコストがb重要でない限り、2つのバージョン間のパフォーマンスの差は小さすぎて検討に値しません。


「実際」の段落は誤解を招くものです。&&を介して&を使用する唯一の理由は、「b」内の自明でない部分式を計算するためです
AlexP

明確にした。(実際、ささいなことは実際には起こりません。)
スティーブンC

51

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

だから、あなたのケースでは、場合b原始的である、a = a && ba = a & b、およびa &= bすべてが同じことを行います。


2
したがって、(a&= b;)は、bがメソッド呼び出しの場合、短絡しませんか?"&& ="演算子のようなものはありますか?
is7s 2012

2
これは質問に答えないようです。OPはすでに短絡について知っていました。
またはMapper '15年


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です。


-2

aが既にfalseの場合にb()を呼び出さないようにするブール値を使用して、同様の状況に遭遇しました。

これは私のために働きました:

a &= a && b()

25
冗長性を回避するために(依然として短絡を可能にする)、単純にと書くことができますa=a&&b()
Unai Vivi 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.