Risposte:
Dalle specifiche del linguaggio Java - 15.26.2 Operatori di assegnazione composti .
Un'espressione di assegnazione composta del modulo
E1 op= E2
è equivalente aE1 = (T)((E1) op (E2))
, dov'èT
il tipo diE1
, tranne cheE1
viene valutata una sola volta.
Quindi a &= b;
è equivalente a a = a & b;
.
(In alcuni usi, il cast del tipo fa la differenza per il risultato, ma in questo b
deve esserlo boolean
e il cast del tipo non fa nulla.)
E, per la cronaca, a &&= b;
non è valido Java. Non c'è nessun &&=
operatore.
In pratica, c'è poca differenza semantica tra a = a & b;
e a = a && b;
. (Se b
è una variabile o una costante, il risultato sarà lo stesso per entrambe le versioni. C'è solo una differenza semantica quando b
c'è una sottoespressione che ha effetti collaterali. Nel &
caso, l'effetto collaterale si verifica sempre. &&
caso si verifica a seconda del valore di a
.)
Dal punto di vista delle prestazioni, il compromesso è tra il costo della valutazione b
e il costo di un test e ramo del valore di a
, e il potenziale risparmio di evitare un'assegnazione non necessaria a a
. L'analisi non è semplice, ma a meno che il costo del calcolo b
non sia banale, la differenza di prestazioni tra le due versioni è troppo piccola per essere presa in considerazione.
vedi 15.22.2 del JLS . Per gli operandi booleani, l' &
operatore è booleano, non bit a bit. L'unica differenza tra &&
e &
per gli operandi booleani è che &&
è cortocircuitato (il che significa che il secondo operando non viene valutato se il primo operando viene valutato come falso).
Quindi nel tuo caso, se b
è un primitivo, a = a && b
, a = a & b
, e a &= b
tutti fanno la stessa cosa.
È l'ultimo:
a = a & b;
Ecco un modo semplice per testarlo:
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;
}
}
L'output è b() was called
, quindi viene valutato l'operando di destra.
Quindi, come già accennato da altri, a &= b
è lo stesso di a = a & b
.
mi sono imbattuto in una situazione simile usando i booleani in cui volevo evitare di chiamare b () se a fosse già falso.
Questo ha funzionato per me:
a &= a && b()
a=a&&b()
.