Zarozumiały
boolean a = false;
Zastanawiałem się, czy robię:
a &= b;
jest równa
a = a && b; //logical AND, a is false hence b is not evaluated.
albo z drugiej strony to znaczy
a = a & b; //Bitwise AND. Both a and b are evaluated.
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 prymitywnya = a && b
,a = a & b
ia &= b
wszystko zrobić to samo.źródło
To ostatnia:
źródło
Oto prosty sposób, aby to przetestować:
Wynik jest
b() was called
, dlatego wartościowany jest prawy operand.Tak więc, jak już wspominali inni,
a &= b
jest taki sam jaka = a & b
.źródło
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:
źródło
a=a&&b()
.