Perché questa istruzione if, con un controllo di assegnazione e uguaglianza, viene valutata come falsa?


105

Come funziona un'istruzione if Java quando ha un compito e un controllo di uguaglianza OR-d insieme ??

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

Perché questa stampa è FALSA?


1
Corri e controlla. Guarda quale valore booleano viene stampato se assegni false e se assegni true. Quindi leggi come funziona OR.
Pratik

2
Vorrei dire che questo codice in modalità debug dà valore TRUE e in modalità Running dà valore FALSE ... Perché è così ??? ... (metto il mio breakpoint su if condition) ...
CoderNeji

test1=false, test1==falseè false, false || falseè false or falsequale è false.
Jared Burrows

So che non stavi chiedendo consiglio, ma poiché le risposte seguenti identificano un problema di precedenza, ecco un paio di pratiche che mi hanno aiutato a evitare problemi (quando mi attengo a queste): (1) usa sempre le parentesi quando non al 100% certo di precedenza o per una più facile leggibilità per aiutare altri sviluppatori. Non dare per scontato che gli altri ricorderanno le regole di precedenza per tutti gli operatori (2) gli assegnamenti if dovrebbero essere generalmente evitati per ridurre la confusione tranne che per condizioni if ​​molto semplici. Ci sono alcune eccezioni comuni (specialmente con semplici controlli per I / O, networking, ecc.). Solo i miei due centesimi.
rimsky

perchétest1 = true
jono

Risposte:


189

L'espressione non è analizzata nel modo in cui pensi. Non è

(test1=false) || (test1 == false)

in tal caso il risultato sarebbe stato true, ma

test1 = (false || test1 == false)

Il valore false || test1 == falsedell'espressione viene calcolato per primo, e lo è false, perché test1è impostato per trueentrare nel calcolo.

Il motivo per cui viene analizzato in questo modo è che la precedenza dell'operatore ||è inferiore a quella ==dell'operatore, ma superiore alla precedenza dell'operatore di assegnazione =.


2
+1 @RohanFernando, tieni presente anche che se aggiungessi parentesi attorno al compito in questo modo: ((test1 = false) || test1 == false)il valore complessivo sarebbe true.
Arnon Zilca

1
Per favore scrivi il motivo per cui l'analisi avviene così ... È a causa dell'ordine di priorità degli operatori?
kondu

3
@kondu Questa è una giusta domanda di follow-up, ho modificato per aggiungere un collegamento a una tabella di precedenza, che mostra che ==è sopra ||, ma =è sotto ||.
dasblinkenlight

L'ultimo paragrafo è fuorviante, nel senso che per capire perché viene scelto il secondo parsing piuttosto che il primo, è sufficiente conoscere la regola (facilmente ricordabile) che l'assegnazione ha la precedenza inferiore a qualsiasi operatore di non assegnazione (qui ||). La precedenza relativa di ||ed ==è rilevante solo per mostrare che l'analisi non è come in test1 = ((false || test1) == false), cosa che non penso che qualcuno si aspetterebbe ragionevolmente (dal modo in cui quella precedenza relativa, o più in generale quella ||, &&ha una precedenza inferiore rispetto alle relazioni, è anche facile da ricorda, poiché usato tutto il tempo).
Marc van Leeuwen

1
@MarcvanLeeuwen La precedenza relativa di ||e ==vs ||e =spiega perché questo si comporta in modo diverso dal caso (comune) di a == b || c == d.
Aaron Dufour

83

Questo è un problema di precedenza, fondamentalmente. Stai assumendo che il tuo codice sia equivalente a:

if ((test1 = false) || (test1 == false))

... ma non lo è. In realtà è equivalente a:

if (test1 = (false || test1 == false))

... che è equivalente a:

if (test1 = (false || false))

(perché test1è trueiniziare con)

... che è equivalente a:

if (test1 = false)

che assegna il valore falsea test1, con il risultato dell'espressione essere false.

Vedere il tutorial Java sugli operatori per un'utile tabella di precedenza degli operatori.


2

dai un'occhiata alla precedenza degli operatori

L'espressione test1 = false || test1 == falsevaluterà nel passaggio successivo.

STEP: 1- test1 = false || test1 == false // la precedenza di ==è la più alta

STEP: 2- test1 = false || false // L'operatore ||ha la precedenza maggiore

PASSO: 3- test1 = false

PASSO: 4- false

Poiché il valore booleano di expression diventa falso, viene eseguita l'istruzione else.


-11

(test1 = false || test1 == false)restituisce false, perché entrambe sono false. (test1 = false || test1 == true)questo è vero perché uno di loro è vero


1
Completamente sbagliato. Perché rispondereste con informazioni così errate giorni dopo che la domanda ha ricevuto due risposte di alta qualità che descrivono cosa succede?
l4mpi

5
Due risposte di così bassa qualità non meritano commenti scritti individualmente. Ti rendi conto che la tua risposta è una sciocchezza, giusto? In caso contrario, leggi attentamente le due risposte di Jon e lampeggia.
l4mpi
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.