Le altre risposte hanno fatto un buon lavoro nel coprire la differenza funzionale tra gli operatori, ma le risposte potrebbero applicarsi a quasi ogni singolo linguaggio derivato dal C esistente oggi. La domanda è taggata conGiavae quindi cercherò di rispondere in modo specifico e tecnico per il linguaggio Java.
&
e |
possono essere operatori Bitwise interi o operatori logici booleani. La sintassi per gli operatori Bitwise e Logical ( §15.22 ) è:
AndExpression:
EqualityExpression
AndExpression & EqualityExpression
ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression ^ AndExpression
InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression | ExclusiveOrExpression
La sintassi per EqualityExpression
è definita in §15.21 , che richiede RelationalExpression
definito in §15.20 , che a sua volta richiede ShiftExpression
e ReferenceType
definito in §15.19 e §4.3 , rispettivamente. ShiftExpression
richiede AdditiveExpression
definito nel §15.18 , che continua a eseguire il drill down, definendo l'aritmetica di base, gli operatori unari, ecc. ReferenceType
esegue il drill down in tutti i vari modi per rappresentare un tipo. (Sebbene ReferenceType
non includa i tipi primitivi, alla fine è necessaria la definizione dei tipi primitivi, poiché potrebbero essere il tipo di dimensione per un array, che è unReferenceType
.)
Gli operatori bit a bit e logici hanno le seguenti proprietà:
- Questi operatori hanno una precedenza diversa, con
&
la precedenza più alta e|
la precedenza più bassa.
- Ognuno di questi operatori è sintatticamente associativo-sinistro (ogni gruppo da sinistra a destra).
- Ogni operatore è commutativo se le espressioni degli operandi non hanno effetti collaterali.
- Ogni operatore è associativo.
- Gli operatori bit per bit e logici possono essere usati per confrontare due operandi di tipo numerico o due operandi di tipo
boolean
. Tutti gli altri casi generano un errore in fase di compilazione.
La distinzione tra se l'operatore funge da operatore bit a bit o come operatore logico dipende dal fatto che gli operandi siano "convertibili in un tipo integrale primitivo" ( §4.2 ) o se siano di tipo boolean
o Boolean
( §5.1.8 ).
Se gli operandi sono di tipo integrale, la promozione numerica binaria ( §5.6.2 ) viene eseguita su entrambi gli operandi, lasciandoli entrambi come long
s o int
s per l'operazione. Il tipo di operazione sarà il tipo di operandi (promossi). A quel punto, &
sarà bit a bit AND, ^
sarà bit a bit OR esclusivo e |
sarà bit a bit OR inclusivo. ( §15.22.1 )
Se gli operandi sono boolean
o Boolean
, gli operandi saranno soggetti a conversione unboxing, se necessario ( §5.1.8 ), e il tipo di operazione sarà boolean
. &
comporterà true
se entrambi gli operandi lo saranno true
, ^
comporterà true
se entrambi gli operandi sono diversi e |
comporterà true
se entrambi gli operandi lo sono true
. ( §15.22.2 )
Al contrario, &&
è "Operatore condizionale" ( §15.23 ) ed ||
è "Operatore condizionale" ( § 15.24 ). La loro sintassi è definita come:
ConditionalAndExpression:
InclusiveOrExpression
ConditionalAndExpression && InclusiveOrExpression
ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression || ConditionalAndExpression
&&
è come &
, tranne per il fatto che valuta l'operando di destra solo se l'operando di sinistra è true
. ||
è come |
, tranne per il fatto che valuta l'operando di destra solo se l'operando di sinistra èfalse
.
Condizionale-E ha le seguenti proprietà:
- L'operatore condizionale e sintatticamente è associativo a sinistra (raggruppa da sinistra a destra).
- L'operatore condizionale e l'operatore sono pienamente associativi rispetto agli effetti collaterali e al valore del risultato. Cioè, per qualsiasi espressione
a
, b
e la c
valutazione dell'espressione ((a) && (b)) && (c)
produce lo stesso risultato, con gli stessi effetti collaterali che si verificano nello stesso ordine, come la valutazione dell'espressione(a) && ((b) && (c))
.
- Ogni operando dell'operatore condizionale e deve essere di tipo
boolean
oBoolean
, oppure si verifica un errore in fase di compilazione.
- Il tipo di un condizionale ed espressione è sempre
boolean
.
- In fase di esecuzione, l'espressione dell'operando di sinistra viene valutata per prima; se il risultato ha tipo
Boolean
, è soggetto a conversione unboxing ( §5.1.8 ).
- Se il valore risultante è
false
, il valore dell'espressione-condizionale è false
e l'espressione dell'operando di destra non viene valutata.
- Se il valore dell'operando di sinistra è
true
, viene valutata l'espressione di destra; se il risultato ha tipo Boolean
, è soggetto a conversione unboxing ( §5.1.8 ). Il valore risultante diventa il valore dell'espressione-condizionale.
- Così,
&&
calcola lo stesso risultato &
su boolean
operandi. Differisce solo dal fatto che l'espressione dell'operando della mano destra viene valutata in modo condizionale piuttosto che sempre.
Condizionale-O ha le seguenti proprietà:
- L'operatore condizionale o sintatticamente è associativo a sinistra (raggruppa da sinistra a destra).
- L'operatore condizionale o è completamente associativo rispetto agli effetti collaterali e al valore del risultato. Cioè, per qualsiasi espressione
a
, b
e c
, la valutazione dell'espressione ((a) || (b)) || (c)
produce lo stesso risultato, con gli stessi effetti collaterali che si verificano nello stesso ordine, come la valutazione dell'espressione (a) || ((b) || (c))
.
- Ogni operando del condizionale o dell'operatore deve essere di tipo
boolean
o Boolean
, oppure si verifica un errore in fase di compilazione.
- Il tipo di un condizionale o espressione è sempre
boolean
.
- In fase di esecuzione, l'espressione dell'operando di sinistra viene valutata per prima; se il risultato ha tipo
Boolean
, è soggetto a conversione unboxing ( §5.1.8 ).
- Se il valore risultante è
true
, il valore dell'espressione condizionale o è true
e l'espressione dell'operando di destra non viene valutata.
- Se il valore dell'operando di sinistra è
false
, viene valutata l'espressione di destra; se il risultato ha tipo Boolean
, è soggetto a conversione unboxing ( §5.1.8 ). Il valore risultante diventa il valore del condizionale o dell'espressione.
- Pertanto,
||
calcola lo stesso risultato di |
on boolean
o Boolean
operandi. Differisce solo dal fatto che l'espressione dell'operando della mano destra viene valutata in modo condizionale piuttosto che sempre.
In breve, come ha sottolineato più volte @JohnMeagher nei commenti, &
e |
in realtà sono operatori booleani non in corto circuito nel caso specifico degli operandi che sono boolean
o Boolean
. Con le buone pratiche (ovvero: nessun effetto secondario), questa è una differenza minore. Quando gli operandi non sono boolean
s o Boolean
s, tuttavia, gli operatori si comportano molto diversamente: bit a bit e operazioni logiche semplicemente non si confronta bene al livello di programmazione Java.