Wendet der Java-Operator & = & oder && an?

139

Vorausgesetzt

boolean a = false;

Ich habe mich gefragt, ob ich Folgendes tun soll:

a &= b; 

ist äquivalent zu

a = a && b; //logical AND, a is false hence b is not evaluated.

oder andererseits bedeutet es

a = a & b; //Bitwise AND. Both a and b are evaluated.
pakore
quelle

Antworten:

146

Aus der Java-Sprachspezifikation - 15.26.2 Compound Assignment Operators .

Eine Verbindung Zuweisungsausdruck von der Form E1 op= E2entspricht E1 = (T)((E1) op (E2)), in dem Tdie Art der E1Ausnahme , dass E1nur einmal ausgewertet wird.

Ist a &= b;also gleichbedeutend mit a = a & b;.

(In einigen Verwendungen macht das Typ-Casting einen Unterschied zum Ergebnis, aber in diesem bmuss es sein booleanund der Typ-Cast tut nichts.)

Und für den Datensatz a &&= b;ist Java nicht gültig. Es gibt keinen &&=Operator.


In der Praxis gibt es kaum einen semantischen Unterschied zwischen a = a & b;und a = a && b;. (Wenn bes sich um eine Variable oder eine Konstante handelt, ist das Ergebnis für beide Versionen gleich. Es gibt nur einen semantischen Unterschied, wenn bein Unterausdruck Nebenwirkungen hat. In diesem &Fall tritt die Nebenwirkung immer auf &&Fall tritt es in Abhängigkeit vom Wert von a.)

Auf der Leistungsseite liegt der Kompromiss zwischen den Kosten für die Bewertung bund den Kosten für einen Test und eine Verzweigung des Werts von aund der potenziellen Einsparung, eine unnötige Zuordnung zu zu vermeiden a. Die Analyse ist nicht einfach, aber wenn die Kosten für die Berechnung bnicht trivial sind, ist der Leistungsunterschied zwischen den beiden Versionen zu gering, um in Betracht gezogen zu werden.

Stephen C.
quelle
Ihr Absatz "in der Praxis" ist irreführend. Der einzige Grund für die Verwendung von & over && ist die Berechnung des nicht trivialen Unterausdrucks in "b"
AlexP
Klargestellt. (Tatsächlich kommt Trivialität nicht wirklich ins Spiel.)
Stephen C
51

siehe 15.22.2 des JLS . Bei booleschen Operanden ist der &Operator boolesch und nicht bitweise. Der einzige Unterschied zwischen &&und &für boolesche Operanden ist der für&& sie kurzgeschlossen sind (was bedeutet, dass der zweite Operand nicht ausgewertet wird, wenn der erste Operand als falsch ausgewertet wird).

Also in Ihrem Fall, wenn bes sich um ein Primitiv a = a && bhandelt a = a & b, und a &= balle das Gleiche tun.

Eintopf
quelle
2
Also wird (a & = b;) nicht kurzschließen, wenn b ein Methodenaufruf ist? Gibt es so etwas wie einen "&& =" Operator?
is7s
2
Es scheint, dass dies die Frage nicht beantwortet; Das OP wusste bereits über Kurzschlüsse Bescheid.
ODER Mapper
21

Es ist der letzte:

a = a & b;
Philippe Leybaert
quelle
0

Hier ist eine einfache Möglichkeit, es zu testen:

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;
    }
}

Die Ausgabe ist b() was called, daher wird der rechte Operand ausgewertet.

Also, wie bereits von anderen erwähnt, a &= bist das gleiche wie a = a & b.

user7291698
quelle
-2

Ich bin auf eine ähnliche Situation mit Booleschen Werten gestoßen, bei der ich vermeiden wollte, b () aufzurufen, wenn a bereits falsch war.

Das hat bei mir funktioniert:

a &= a && b()
Daniel Testa
quelle
25
Um Redundanzen zu vermeiden (immer noch Kurzschlüsse), können Sie einfach schreiben a=a&&b().
Unai Vivi