Odpowiedzi:
Ze specyfikacji języka Java - 15.26.2 złożone operatory przypisania .
Wyrażenie przypisania złożonego formularza
E1 op= E2
jest równoważne zE1 = (T)((E1) op (E2))
, gdzieT
jest typemE1
, z wyjątkiem tego, żeE1
jest oceniane tylko raz.
Więc a &= b;
jest równoważne a = a & b;
.
(W niektórych zastosowaniach rzutowanie typów ma wpływ na wynik, ale w tym b
musi być, boolean
a rzutowanie typu nic nie robi).
I dla przypomnienia, a &&= b;
nie jest to poprawna Java. Nie ma &&=
operatora.
W praktyce istnieje niewielka różnica semantyczna między a = a & b;
i a = a && b;
. (Jeśli b
jest to zmienna lub stała, wynik będzie taki sam dla obu wersji. Jest tylko semantyczna różnica, gdy b
istnieje podwyrażenie, które ma skutki uboczne. W takim &
przypadku efekt uboczny występuje zawsze. &&
przypadku występuje w zależności od wartości a
.)
Po stronie wydajności kompromis jest między kosztem oceny b
a kosztem testu i gałęzi wartości a
, a potencjalnymi oszczędnościami wynikającymi z uniknięcia niepotrzebnego przypisywania do a
. Analiza nie jest prosta, ale o ile koszt obliczeń b
nie jest nietrywialny, różnica w wydajności między tymi dwiema wersjami jest zbyt mała, aby warto ją rozważyć.
patrz 15.22.2 JLS . W przypadku operandów logicznych &
operator jest logiczny, a nie bitowy. Jedyną różnicą między &&
i &
dla operandów boolowskich jest to, &&
że są one zwarte (co oznacza, że drugi operand nie jest oceniany, jeśli pierwszy argument ma wartość false).
Tak więc w przypadku, jeśli b
jest prymitywny a = a && b
, a = a & b
i a &= b
wszystko zrobić to samo.
To ostatnia:
a = a & b;
Oto prosty sposób, aby to przetestować:
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;
}
}
Wynik jest b() was called
, dlatego wartościowany jest prawy operand.
Tak więc, jak już wspominali inni, a &= b
jest taki sam jak a = a & b
.
Natknąłem się na podobną sytuację, używając wartości logicznych, w których chciałem uniknąć wywołania b (), jeśli a było już fałszywe.
To zadziałało dla mnie:
a &= a && b()
a=a&&b()
.