L'operatore Java & = applica & o &&?


139

assumendo

boolean a = false;

Mi chiedevo se facendo:

a &= b; 

è equivalente a

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

o d'altra parte significa

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

Risposte:


146

Dalle specifiche del linguaggio Java - 15.26.2 Operatori di assegnazione composti .

Un'espressione di assegnazione composta del modulo E1 op= E2è equivalente a E1 = (T)((E1) op (E2)), dov'è Til tipo di E1, tranne che E1viene 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 bdeve esserlo booleane 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 bc'è 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 be 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 bnon sia banale, la differenza di prestazioni tra le due versioni è troppo piccola per essere presa in considerazione.


Il tuo paragrafo "in pratica" è fuorviante. L'unico motivo per usare & over && è calcolare una sottoespressione non banale in "b"
AlexP

Chiarito. (In effetti, la banalità non ci arriva davvero.)
Stephen C,

51

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 &= btutti fanno la stessa cosa.


2
Quindi (a & = b;) non andrà in corto circuito se b è una chiamata di metodo? c'è qualcosa come un operatore "&& ="?
Is7s

2
Sembra che questo non risponda alla domanda; l'OP sapeva già del corto circuito.
OR Mapper,


0

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.


-2

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()

25
Al fine di evitare ridondanze (consentendo comunque il cortocircuito), è possibile semplicemente scrivere a=a&&b().
Unai Vivi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.