2014-06-12 18 views
5

Quando c'è una dichiarazione scritta dopo il ciclo infinito, quella istruzione diventa il codice irraggiungibile. Per esempio:Quando si verifica la condizione "Codice non raggiungibile" in Java?

for(;;) 
{ 
} 
Sytem.out.println("Test-1"); //unreachable code 

Ma sto affrontando qualche difficoltà qui.

Guardate i due frammenti di codice qui sotto:

Codice snippet1:

for(final int z=4;z<6;) 
{ 
} 
System.out.println("Test-2"); //unreachable code 

Qui, L'ultima istruzione deve essere raggiungibile perché il ciclo è infinito e l'uscita è come previsto.

Codice Snippet2:

final int z=4; 
for(;;) 
{ 
    if(z<2) 
     break; 
} 
System.out.println("Test-3"); //not unreachable 

Concettualmente, il ciclo di codice sopra è anche infinita poiché z è definitiva e if(z<2) è determinato in fase di compilazione only.The se la condizione non sarà mai vera e il loop mai rompere. Ma l'ultima frase nel codice sopra non è irraggiungibile.

Domande:

  1. perché questo sta accadendo?

  2. Qualcuno può dirmi le regole esatte in base alle quali possiamo vedere se il codice è irraggiungibile o meno.

+7

La specifica del linguaggio Java ha la risposta: [Dichiarazioni irraggiungibili] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21) – Christian

+2

@Gynnad, tu interrompe solo se z <2, che non è. (La domanda potrebbe essere stata cambiata) – Holloway

risposta

3

La frase chiave in http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21 è:

Si tratta di un errore di compilazione se una dichiarazione non può essere eseguita perché è irraggiungibile.

Questa sezione è dedicata a una spiegazione precisa della parola "raggiungibile". L'idea è che ci deve essere un possibile percorso di esecuzione dall'inizio del costruttore, metodo, istanza inizializzatore o inizializzatore statico che contiene l'istruzione nell'istruzione stessa. L'analisi tiene conto della struttura delle dichiarazioni . Fatta eccezione per il trattamento speciale di while, do e per le espressioni la cui espressione di condizione ha il valore costante true, i valori di espressione non vengono presi in considerazione nell'analisi del flusso.

Quindi il compilatore non valuta z<2 nel vostro if() dichiarazione, e non sa che non potrà mai restituire true.

Definisce il codice non raggiungibile per quanto riguarda le specifiche Java. È importante che i compilatori aderiscano alle specifiche, poiché la modifica delle regole potrebbe rendere impossibile compilare il codice utilizzato per compilare.

Tuttavia, i compilatori sono liberi di dare avvisi piuttosto che errori di compilazione.

Se digito il seguente codice in Eclipse:

final int x = 0; 
if(x == 1) { 
    System.out.println("This never happens"); 
} 

... ottengo l'avvertimento "codice morto". Il compilatore sa che il codice non può essere raggiunto - ma non può rifiutarsi di compilare, perché il codice non è formalmente "irraggiungibile" secondo le specifiche Java.

+0

Sì, ha aiutato. Ma dopo aver letto questo altro dubbio mi è saltato in testa. Prendiamo un esempio: codice1: 'int a = 4, b; if (a == 4) b = 5; System.out.println (b); // error-b potrebbe non essere stato inizializzato ' Ciò è perfettamente vero perché l'inizializzazione di b è all'interno di se. Ma, nel seguente codice: finale int a = 4, b; if (a == 4) b = 5; System.out.println (b); // non dà errore ' In base alla discussione precedente, anche questo dovrebbe mostrare errore poiché il valore dell'espressione in condizione if non deve essere valutato. –

+0

In tal caso l'errore non è "Codice non raggiungibile", quindi le specifiche in quella sezione non si applicano. Quello che hai è un'espressione costante che valuta 'if (true)' in fase di compilazione. Il compilatore rimuoverà 'if() 'completamente fuori e solo inline' b = 5'. È un 'espressione costante' perché 'a' è' finale'. – slim

+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 – slim

0
for(final int z=4;z<6;) 
{ 
} 
System.out.println("Test-2"); //unreachable code --> z is final. Its value can't change. There is no way out of that loop 



final int z=4; 
for(;;) 
{ 
    if(z<2) // z is 4 . The compiler only knows the value of "z". It doesn't know what z<2 evaluates to.. So, it still thinks taht there is a chance of getting out of that loop. 
break; 
} 
System.out.println("Test-3"); //So --> reachable code. 
+0

Si prega di guardare nuovamente il codice snippet-2. La sua z <2 lì. –

+0

@VikasMangal - controlla la mia modifica .. – TheLostMind

2

Da http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

14,21. Dichiarazioni irraggiungibili

Si tratta di un errore in fase di compilazione se un'istruzione non può essere eseguita perché non è raggiungibile.

Questa sezione è dedicata a una spiegazione precisa della parola "raggiungibile". L'idea è che ci deve essere un possibile percorso di esecuzione dall'inizio del costruttore, metodo, istanza inizializzatore o inizializzatore statico che contiene l'istruzione nell'istruzione stessa. L'analisi tiene conto della struttura delle dichiarazioni . Fatta eccezione per il trattamento speciale di while, do e per le istruzioni la cui espressione condizionale ha il valore costante true, i valori delle espressioni non vengono presi in considerazione nell'analisi del flusso.

Ad esempio, un compilatore Java accetterà il codice:

{ int n = 5; while (n> 7) k = 2; } anche se il valore di n è noto in fase di compilazione e in linea di principio si può sapere in fase di compilazione che l'assegnazione di a k non può mai essere eseguita.

Le regole in questa sezione definiscono due termini tecnici:

se una dichiarazione è raggiungibile

se un enunciato può completare normalmente

Le definizioni qui consentono una comunicazione per completare normalmente solo se è raggiungibile

Per abbreviare la descrizione delle regole, l'abbreviazione abituale "iff" viene utilizzata per indicare "se e solo se".

Un'istruzione break raggiungibile esce una dichiarazione se, entro il bersaglio pausa , o non ci sono istruzioni try cui provare blocchi contengono l'istruzione break, o ci sono provare dichiarazioni il cui provare blocchi contengono l'istruzione break e tutti finalmente le clausole di coloro che provano le dichiarazioni possono completare normalmente.

Questa definizione è basata sulla logica intorno "tenta di trasferire il controllo " in §14.15.

Un'istruzione continue continua una dichiarazione fare se, nel fare dichiarazione, o non ci sono istruzioni try cui provare blocchi contenere l'istruzione continue, o ci sono provate le dichiarazioni la cui provare blocchi contengono l'istruzione continue e tutti finalmente le clausole di coloro che provano le dichiarazioni possono completare normalmente.

Le regole sono come segue:

Il blocco che è il corpo di un costruttore, metodo, esempio inizializzatore, o inizializzatore statico è raggiungibile.

Un blocco vuoto che non è un blocco di interruttori può essere completato normalmente se è disponibile il numero .

Un blocco non vuoto che non è un blocco di interruttori può essere completato normalmente se l'ultima istruzione in esso può essere completata normalmente.

La prima istruzione in un blocco non vuoto che non è un blocco di commutazione è raggiungibile se il blocco è raggiungibile.

Ogni altra istruzione S in un blocco non vuoto che non sia un blocco è raggiungibile se l'istruzione che precede S può completare normalmente .

Una dichiarazione di dichiarazione di classe locale può essere completata normalmente se è possibile raggiungere .

Una dichiarazione di dichiarazione di variabile locale può essere completata normalmente se è raggiungibile.

Un'istruzione vuota può essere completata normalmente se è raggiungibile.

Una dichiarazione marcata può completare normalmente se almeno uno dei seguenti condizioni:

L'affermazione contenuta in grado di completare normalmente.

C'è un'istruzione break accessibile che esce dall'istruzione etichettata.

L'istruzione contenuta è raggiungibile se l'istruzione etichettata è raggiungibile.

Un'istruzione espressione può essere completata normalmente se è raggiungibile.

Un'istruzione if-then può essere completata normalmente se è raggiungibile.

L'istruzione then è raggiungibile se l'istruzione if-then è raggiungibile.

Un'istruzione if-then-else può essere completata normalmente se l'istruzione then può completare normalmente o l'istruzione else può completare normalmente.

L'istruzione then è raggiungibile se l'istruzione if-then-else è raggiungibile.

L'istruzione else è raggiungibile se l'istruzione if-then-else è raggiungibile.

Questa gestione di un'istruzione if, anche se non ha un'altra parte, è piuttosto insolita. La motivazione è fornita alla fine di questa sezione.

Una dichiarazione di asserzione può essere completata normalmente se è raggiungibile.

Un'istruzione switch può completare normalmente sse almeno uno dei seguenti condizioni:

Il blocco interruttore è vuoto o contiene solo passare etichette.

L'ultima istruzione nel blocco di commutazione può essere completata normalmente.

C'è almeno un'etichetta di commutazione dopo l'ultimo gruppo di blocchi .

Il blocco di commutazione non contiene un'etichetta predefinita.

C'è un'istruzione break raggiungibile che esce dall'istruzione switch.

Un blocco di commutazione è raggiungibile se l'istruzione switch è raggiungibile.

Un'istruzione in un blocco interruttore è raggiungibile sse suo controllo switch raggiungibile e almeno una delle seguenti condizioni:

Esso reca un'etichetta caso o di default.

C'è una dichiarazione che la precede nel blocco di commutazione e che l'istruzione precedente può completare normalmente.

Un while possibile completare normalmente IFF almeno una delle seguente è vera:

L'istruzione while è raggiungibile e l'espressione condizione non è una costante espressione (§15.28) con il valore true.

C'è un'istruzione break accessibile che esce dall'istruzione while.

L'istruzione contenuta è raggiungibile se l'istruzione while è raggiungibile e l'espressione di condizione non è un'espressione costante il cui valore è falso.

Un fanno affermazione può completare normalmente sse almeno una delle seguenti è vero:

L'affermazione contenuta può completare normalmente e l'espressione condizione non è un'espressione costante (§15.28) con il valore true.

Il do istruzione contiene un raggiungibile istruzione continue senza etichetta, e la do istruzione è l'istante più interno, do, o per dichiarazione che contiene tale istruzione continue, e il procedi dichiarazione continua che istruzione do, e la espressione condizionale è non un'espressione costante con valore true.

Il do istruzione contiene raggiungibile istruzione continue con un'etichetta L, e il comando do ha etichetta L, e l'istruzione continue continua che fanno affermazione e l'espressione condizione non è una costante un'espressione con valore true.

C'è un'istruzione break accessibile che esce dall'istruzione do.

L'istruzione contenuta è raggiungibile se l'istruzione do è raggiungibile.

Una base per istruzione possibile completare normalmente sse almeno uno dei seguenti condizioni:

L'istruzione è raggiungibile, c'è un'espressione condizione, e l'espressione condizione non è un'espressione costante (§ 15.28) con il valore true.

C'è un'istruzione break accessibile che esce dall'istruzione for.

L'istruzione contenuta è raggiungibile se l'istruzione for è raggiungibile e l'espressione di condizione non è un'espressione costante il cui valore è falso.

Un'istruzione potenziata può essere completata normalmente se è raggiungibile.

Un'istruzione break, continue, return o throw non può completare normalmente .

Una istruzione sincronizzata può essere completata normalmente se l'istruzione contenuta può essere completata normalmente.

L'istruzione contenuta è raggiungibile se l'istruzione sincronizzata è raggiungibile.

Un'istruzione try può completare normalmente se e solo se entrambe le seguenti sono vere:

Il blocco try può completare normalmente o qualsiasi blocco catch può completare normalmente.

Se l'istruzione try ha un blocco finally, il blocco finally può completare normalmente.

Il blocco try è raggiungibile se l'istruzione try è raggiungibile.

Un blocco catch C è raggiungibile se e solo se entrambi seguente requisito:

sia il tipo di parametro di C è un tipo di eccezione ignorati o Throwable; o qualche istruzione di espressione o laterale nel blocco try è raggiungibile e può lanciare un'eccezione controllata cui tipo è assegnabile al parametro della clausola catch C.

Un'espressione è raggiungibile sse comunicazione interna che lo contiene è raggiungibile .

Vedere §15.6 per il completamento normale e improvviso delle espressioni.

Non esiste un blocco di cattura A precedente nella dichiarazione try tale che il tipo di parametro C sia uguale o una sottoclasse del tipo di parametro di A.

Il blocco di un blocco catch è raggiungibile se il blocco catch è raggiungibile.

Se un blocco finally è presente, è raggiungibile se l'istruzione try è raggiungibile.

Problemi correlati