2012-10-07 6 views
12

Ho commesso un errore di codifica mentre lavoravo a un'applicazione, era un test per riferimento null. Mi ci sono volute ore per scoprire quale fosse il problema, ma ciò che non capisco è perché il codice si è comportato in questo modo.Perché l'istruzione java if fallisce quando termina con punto e virgola

String name = null; 
String value = null; 

if(name != null && value != null); 
{ 
    System.out.println("Values not null"); 
} 

l'istruzione if è conclusa con ;, che è stato il mio errore e la Values not null è stato stampato anche quando è evidente che entrambi i valori sono nulli. Qualcuno può spiegare perché?

risposta

14

questo punto e virgola termina una dichiarazione (uno vuoto), quindi il codice è tradotto dal compilatore per qualcosa di simile:

if(name != null && value != null) 
{ 
    //nothing here 
} 
{ 
    System.out.println("Values not null"); 
} 

In altre parole, se l'espressione if è true, esegue il blocco di codice vuoto. Quindi, a prescindere dal fatto che if fosse vero o meno, il runtime procede e avvia il blocco contenente System.out. L'istruzione vuota è ancora una dichiarazione, quindi il compilatore accetta il tuo codice.

Un altro posto in cui un simile errore può capitare:

for(int i = 0; i < 10; ++i); 
{ 
    System.out.println("Y U always run once?"); 
} 

o peggio ancora (ciclo infinito):

boolean stop = false; 
while(!stop); 
{ 
    //... 
    stop = true; 
} 

ci ho messo ore per scoprire quale sia il problema era

Il buono IDE dovrebbe avvisarti immediatamente di tale affermazione poichè probabilmente non sarà mai c orrect (come if(x = 7) in alcune lingue).

+0

ho usato NetBeans, ma non mi ha avvertito. –

+0

@UchennaNwanyanwu: può prova chiunque in Eclipse? Solo curioso ... –

+0

@TomaszNurkiewicz .. Un IDE non ti avviserà di questo .. Non è considerato come un uso errato di se .. –

2
if(name != null && value != null); 
{ 
    System.out.println("Values not null"); 
} 

è equivalente a:

if(name != null && value != null){} 

{ 
    System.out.println("Values not null"); 
} 
2
if(name != null && value != null); 

Qui la vostra istruzione if ottenuto finito a causa di punto e virgola ...

così, è proprio come un empty blocco if: -

if(name != null && value != null) {} 

Quindi il prossimo codice diventa un blocco Initializer: -

{ 
    System.out.println("Values not null"); 
} 

Poiché è un blocco di inizializzazione .. Verrà eseguito sempre a prescindere da quale sia la tua condizionevalutata a ..

1

Sono le regole grammaticali standard.Virgola terminano dichiarazioni, ma affermazioni possono essere vuote, così queste linee:

if (...); 
{ 
} 

sono equivalenti a:

if (...) /* do nothing */ ; 

{ 
    ... 
} 

Il { ... } dichiarazione seguente appare come qualsiasi altro blocco di codice, e sarà sempre eseguito, perché l'istruzione if è terminata da allora.

1

Il codice è equivalente a:

if(name != null && value != null) { 
    // empty code block 
} 

System.out.println("Values not null"); 
5

; termina la dichiarazione.

if(name != null && value != null); 

è equivalente a:

if(name != null && value != null) 
{ 
} 

E il seguente codice è semplicemente un blocco di codice.

1

La virgola termina l'istruzione, e quindi si stacca il caso dal blocco successivo.

noti che i blocchi possono essere arbitrario.

{ 
System.out.println("This is some code"); 
} 

if(true); Questo è valido, e non fa nulla. Il linguaggio che consente questo è abbastanza stupido, anche se gli IDE dovrebbero cogliere questi problemi con avvertimenti e simili.

0

Uno spoglio ; è un'intera frase vuota. Dopo il se ci deve essere esattamente una dichiarazione che verrà eseguito quando if è vero. L'unica istruzione che viene eseguita nel tuo caso è l'istruzione vuota. È possibile combinare più istruzioni in una con {statement; statement;...}

0

Comprendere che le istruzioni condizionali non devono necessariamente seguire le parentesi graffe di apertura e di chiusura. La maggior parte delle lingue vi permetterà di emettere semplicemente le parentesi se si desidera solo eseguire una singola istruzione quando sono soddisfatte le condizioni della condizione.

senso che la segue è del tutto valido, ad esempio:

if (var1 == true && var2 == true) var3 = 'both true'; 
{ 
    //block here, this is always executed regardless of the statements outcome 
} 

In sostanza, il codice fa esattamente questo. Tranne che la sua dichiarazione singolo è determinato ad essere ; (sì, questo è considerato una dichiarazione).

Quello che hai scritto è lo stesso:

if(name != null && value != null) { 
    // do nothing 
} 

System.out.println("Values not null"); 
Problemi correlati