Risposte:
Questi sono gli operatori AND bit per bit e OR bit per bit.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Grazie a Carlos per aver indicato la sezione appropriata nelle specifiche del linguaggio Java ( 15.22.1 , 15.22.2 ) riguardante i diversi comportamenti dell'operatore in base ai suoi input.
Infatti, quando entrambi gli input sono booleani, gli operatori sono considerati gli operatori logici booleani e si comportano in modo simile agli operatori Conditional-And ( &&
) e Conditional-Or ( ||
) tranne per il fatto che non vanno in cortocircuito quindi mentre quanto segue è sicuro :
if((a != null) && (a.something == 3)){
}
Questo non è:
if((a != null) & (a.something == 3)){
}
"Cortocircuito" significa che l'operatore non esamina necessariamente tutte le condizioni. Negli esempi precedenti, &&
esamineremo la seconda condizione solo quando a
non lo è null
(altrimenti l'intera istruzione restituirà false, e sarebbe comunque discutibile esaminare le seguenti condizioni), quindi l'affermazione di a.something
non solleverà un'eccezione o è considerata "sicura ".
L' &
operatore esamina sempre ogni condizione nella clausola, quindi negli esempi precedenti, a.something
può essere valutata quando a
è in realtà un null
valore, sollevando un'eccezione.
Penso che tu stia parlando del significato logico di entrambi gli operatori, qui hai un curriculum tabella:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
La valutazione di cortocircuito , la valutazione minima o la valutazione di McCarthy (dopo John McCarthy) sono la semantica di alcuni operatori booleani in alcuni linguaggi di programmazione in cui il secondo argomento viene eseguito o valutato solo se il primo argomento non è sufficiente a determinare il valore del espressione: quando il primo argomento della funzione AND restituisce falso, il valore complessivo deve essere falso; e quando il primo argomento della funzione OR restituisce true, il valore complessivo deve essere true.
Non sicuro significa che l'operatore esamina sempre ogni condizione nella clausola, quindi negli esempi precedenti, 1 / x può essere valutato quando x è, in effetti, un valore 0, sollevando un'eccezione.
So che ci sono molte risposte qui, ma sembrano tutte un po 'confuse. Quindi, dopo aver fatto alcune ricerche dalla guida allo studio di Oracle Oracle, ho escogitato tre diversi scenari in cui utilizzare && o &. I tre scenari sono AND logico , AND bit per bit e AND booleano .
AND logico: AND
logico (noto anche come AND condizionale) utilizza l' operatore && . Ha un significato cortocircuitato: se l'operando sinistro è falso, l'operando destro non verrà valutato.
Esempio:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
Nell'esempio sopra il valore stampato sulla console di x sarà 0, perché il primo operando nell'istruzione if è falso, quindi java non ha bisogno di calcolare (1 == ++ x) quindi x non verrà calcolato.
AND bit per bit: AND bit per bit utilizza l' operatore & . Viene utilizzato per eseguire un'operazione bit per bit sul valore. È molto più facile vedere cosa sta succedendo guardando le operazioni sui numeri binari es:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Come puoi vedere nell'esempio, quando le rappresentazioni binarie dei numeri 5 e 12 sono allineate, un AND bit per bit preformato produrrà solo un numero binario in cui la stessa cifra in entrambi i numeri ha un 1. Quindi 0101 e 1100 == 0100. Che in decimale è 5 e 12 == 4.
AND booleano: ora l'operatore AND booleano si comporta in modo simile e diverso sia per l'operatore AND bit per bit che per l'operatore AND logico. Mi piace pensare che preforma un AND bit per bit tra due valori booleani (o bit), quindi utilizza l' operatore & . Anche i valori booleani possono essere il risultato di un'espressione logica.
Restituisce un valore vero o falso, molto simile al logico AND, ma a differenza del logico AND non è in cortocircuito. Il motivo è che, per eseguire l'operatore AND bit per bit, deve conoscere il valore di entrambi gli operandi sinistro e destro. Ecco un ex:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Ora, quando viene eseguita l'istruzione if, verrà eseguita l'espressione (1 == ++ x), anche se l'operando sinistro è falso. Quindi il valore stampato per x sarà 1 perché è stato incrementato.
Questo vale anche per OR logico (||), OR bit per bit (|) e OR booleano (|) Spero che questo chiarisca un po 'di confusione.
to preform that bitwise AND, it must know the value of both left and right operands
Questo non mi sembra giusto. Per eseguire un BITWISE AND
non è necessario conoscere l'operando di destra per poter capire il risultato se l'operando di sinistra è FALSE
. Quello che spieghi è corretto, ma il ragionamento che dici non sembra così, almeno a me ..
Gli operatori && e || sono in corto circuito, nel senso che non valuteranno la loro espressione della mano destra se il valore dell'espressione della mano sinistra è sufficiente per determinare il risultato.
& e | forniscono lo stesso risultato di && e || operatori. La differenza è che valutano sempre entrambi i lati dell'espressione dove come && e || smettere di valutare se la prima condizione è sufficiente per determinare il risultato.
&&
valuta entrambi i risultati mentre ||
restituisce solo se la prima condizione è vera.
( 2 & 4 )
restituisce false
, mentre ( 2 && 4 )
restituisce true
. In che modo esattamente è lo stesso risultato?
2 & 4
restituisce un numero intero, non un booleano (zero in questo caso). 2 && 4
non verrà compilato, && accetta solo valori booleani. Java non consente di mescolare booleani e int: zero non è false
, false
non è zero ...
&&
valuta solo il secondo operando se il primo è true
.
In Java, i singoli operatori &, |, ^,! dipendono dagli operandi. Se entrambi gli operandi sono interi, viene eseguita un'operazione bit per bit. Se entrambi sono booleani, viene eseguita un'operazione "logica".
Se entrambi gli operandi non corrispondono, viene generato un errore in fase di compilazione.
I doppi operatori &&, || si comportano in modo simile alle loro singole controparti, ma entrambi gli operandi devono essere espressioni condizionali, ad esempio:
if ((a <0) && (b <0)) {...} o similmente, if ((a <0) || (b <0)) {...}
fonte: programmazione java lang 4th ed
&
e |
sono operatori bit per bit sui tipi integrali (ad esempio int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
e ||
operano solo su valori booleani (e cortocircuiti, come già detto in altre risposte).
&
e |
sono anche operatori booleani sui tipi booleani.
Forse può essere utile sapere che gli operatori AND bit per bit e OR bit per bit vengono sempre valutati prima di AND condizionale e OR condizionale utilizzati nella stessa espressione.
if ( (1>2) && (2>1) | true) // false!
&&; || sono operatori logici .... cortocircuito
&; | sono operatori logici booleani .... Non cortocircuito
Passando alle differenze nell'esecuzione delle espressioni. Gli operatori bit per bit valutano entrambi i lati indipendentemente dal risultato del lato sinistro. Ma nel caso della valutazione di espressioni con operatori logici, la valutazione dell'espressione della mano destra dipende dalla condizione della mano sinistra.
Per esempio:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Questo stamperà i = 26; j = 25, poiché la prima condizione è falsa, la condizione della mano destra viene bypassata poiché il risultato è comunque falso indipendentemente dalla condizione del lato destro. (cortocircuito)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Ma questo stamperà i = 26; j = 26,
Se viene valutata un'espressione che coinvolge l' operatore booleano & , vengono valutati entrambi gli operandi. Quindi l'operatore & viene applicato all'operando.
Quando viene valutata un'espressione che coinvolge l' operatore && , viene valutato il primo operando. Se il primo operando restituisce false, la valutazione del secondo operando viene ignorata.
Se il primo operando restituisce un valore true, viene valutato il secondo operando. Se il secondo operando restituisce un valore true, l'operatore && viene quindi applicato al primo e al secondo operando.
Simile per | e ||.
Mentre la differenza fondamentale è che &
viene utilizzato per operazioni bit per bit principalmente su long
, int
o byte
dove può essere utilizzato per una sorta di maschera, i risultati possono differire anche se lo si utilizza invece di logica &&
.
La differenza è più evidente in alcuni scenari:
Il primo punto è abbastanza semplice, non causa bug, ma richiede più tempo. Se hai diversi controlli in una sola istruzione condizionale, metti quelli che sono più economici o che hanno maggiori probabilità di fallire a sinistra.
Per il secondo punto, guarda questo esempio:
if ((a != null) & (a.isEmpty()))
Ciò non riesce null
, poiché la valutazione della seconda espressione produce a NullPointerException
. L'operatore logico &&
è pigro, se l'operando di sinistra è falso, il risultato è falso indipendentemente dall'operando di destra.
Esempio per il terzo punto: supponiamo di avere un'app che utilizza DB senza trigger o cascate. Prima di rimuovere un oggetto Edificio, è necessario modificare l'edificio di un oggetto Reparto con un altro. Diciamo anche che lo stato dell'operazione viene restituito come booleano (vero = successo). Poi:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Questo valuta entrambe le espressioni e quindi esegue la rimozione dell'edificio anche se l'aggiornamento del reparto non è riuscito per qualche motivo. Con &&
, funziona come previsto e si ferma dopo il primo guasto.
Quanto a a || b
, è equivalente a !(!a && !b)
, si ferma se a
è vero, non è necessaria alcuna spiegazione.