2015-05-04 18 views
14

Mentre stavo leggendo il codice Java di un collega, mi sono imbattuto in un esercito di dichiarazioni if ​​/ else. In queste dichiarazioni, diversi operatori && e || si stavano combattendo tra loro senza l'aiuto di parentesi. Ho semplificato le dichiarazioni in:Operatore logico Java (&&, ||) meccanismo di cortocircuito

if (true || true && false) 
    return true; 
else 
    return false; 

Quale pensi che sarebbe il risultato? Onestamente, ho pensato che sarebbe false, ma sembra che il cortocircuito non funzioni come mi aspettavo. In questo caso, il risultato è true. Il meccanismo di cortocircuito sembra considerare l'intera espressione come true quando trova true seguito immediatamente da ||.

Ma nell'espressione invertita, qual è il risultato?

if (false && true || true) 
    return true; 
else 
    return false; 

Se seguiamo la stessa logica, dovrebbe essere falso. il primo booleano è false ed è immediatamente seguito da &&, ma il risultato è true, ancora una volta. Questo ha senso per me, ma sembra incompatibile con il nostro precedente esperimento.

Quindi, ecco la mia teoria:

Se troviamo un true seguita da ||, allora è true, non importa ciò che potrebbe viene dopo, anche se v'è una lunga lista di altri operatori logici che viene dopo. Ma se troviamo false seguito da &&, cortocircuiterà solo l'elemento successivo, non l'intera istruzione.

Ed ecco la mia domanda:

ho ragione? Mi sembra un po 'sciocco. true è più forte di false?

+19

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html '&&' ha una precedenza più alta di '||' come menzionato nelle risposte esistenti (volevo solo fornire il link) –

+1

In ogni caso dovresti chiedere al tuo collega di scrivere parentesi in questo caso, per evitare errori che potrebbero accadere quando qualcuno aggiungi una nuova condizione in questo codice! – Joel

+0

Penso che tu stia (parzialmente) facendo la domanda sbagliata. La domanda corretta è: si dovrebbe scrivere un codice come questo; e la risposta è: no, non dovresti. – GhostCat

risposta

58

è semplicemente perché

if (false && true || true) 

è equivalente a (&& ha una maggiore precedence)

if ((false && true) || true) 

che è

if (false || true) 

che è ... true.

Nota: Nell'espressione true || true && false, la parte true && false si chiama codice morto perché non influisce sul risultato finale della valutazione, dal momento che è sempre true || anythingtrue.


Vale la pena ricordare che esistono & e | operatori che possono essere applicate a booleani, sono molto simili && e || salvo che non lo fanno corto circuito, il che significa che se si ha la seguente espressione:

if (someMethod() & anotherMethod()) 

e someMethod ritorna false, saranno ancora raggiunti anotherMethod! Ma lo if non verrà eseguito perché il risultato finale verrà valutato su false.

+4

OK, quindi funziona come "1 + 1 * 2 = 3". Non sapevo una cosa del genere (la precedenza), esisteva per il && e || operatori. Grazie mille :) –

+5

@JasonBerger 'false && true || true' è molto simile a '0 * 1 + 1', vedi [Algebra Booleana] (http://en.wikipedia.org/wiki/Boolean_algebra#Basic_operations) per dettagli – schnittstabil

+5

' if (someMethod() & anotherMethod()) '- Non incoraggiare la scrittura di codice come questo. Questo dovrebbe essere diviso in più righe. –

15

Il && ha precedenza di funzionamento superiore su ||, quindi vince.

5

per &&:

falsi & & ... = > false

per ||:

vero || ... => vero.

E la precedenza per && è superiore a ||.

Guarda anche: Operator Precedence in Java

8

Secondo Java tutorials&& ha elevato la precedenza su ||

Così il vostro true || true && false sarebbe stato valutato come true || (true && false)

E il tuo false && true || true sarebbe stato valutato come (false && true) || true

risultante in un'uscita di true in entrambi i casi.

1

Vedo cosa stavi tentando di fare, ma prima di utilizzare le parentesi è utile avere le specifiche della lingua a portata di mano. Ho conosciuto alcuni programmatori che sono andati così lontano da mantenere le parti importanti, come la precedenza degli operatori, sulle loro pareti.

La seconda parte è sapere se le vostre modifiche avranno un senso per le altre persone sul posto di lavoro; se la rimozione di parentesi compromette il significato di un'operazione a qualcun altro che lavora sul codice, allora potrebbe essere in definitiva dannosa.

L'ottimizzatore in genere si prenderà cura di esso per te, quindi in caso di dubbio, lasciarli lì.