2012-05-30 5 views
81

Ho una domanda pazzesca sugli switch Java.Dichiarazione e inizializzazione delle variabili all'interno degli switch Java

int key = 2; 

switch (key) { 
    case 1: 
     int value = 1; 
     break; 
    case 2: 
     value = 2; 
     System.out.println(value); 
     break; 
    default: 
     break; 
} 

Scenario 1 - Quando il key è due esso stampa con successo il valore come 2.
Scenario 2 - Quando ho intenzione di commentare value = 2 in case 2: esso squawks dicendo che la Il valore variabile locale non può avere stato inizializzato.

Domande:

Scenario 1: se il flusso di esecuzione non va a case 1: (quando il key = 2), poi come fa a sapere il tipo della variabile valore come int?

Scenario 2: se il compilatore conosce il tipo della variabile di valore come int, deve avere accesso all'espressione int value = 1; in case 1:. (Dichiarazione e inizializzazione). Quindi, perché sqawrk Quando ho intenzione di commentare value = 2 in case 2:, dicendo il Il valore della variabile locale potrebbe non essere stato inizializzato.

+9

Non è una domanda folle, è una buona domanda. – biziclop

+0

Possibile duplicato dell'ambito [Variable's scope in switch case] (http://stackoverflow.com/questions/3894119/variables-scope-in-a-switch-case) –

+0

@PhilippeCarriere In realtà, penso che dovrebbe essere al contrario - la risposta qui è migliore (anche se il post è più recente) poiché c'è un riferimento diretto al JLS e riassume bene il problema trattato in diverse risposte in quel post. [Vedi anche] (http://meta.stackoverflow.com/questions/251938/should-i-flag-a-question-as-duplicate-if-it-has-received-better-answers). – Tunaki

risposta

96

Le istruzioni di commutazione sono dispari in termini di ambito, in sostanza. Da section 6.3 of the JLS:

L'ambito di una dichiarazione variabile locale in un blocco (§14.4) è il resto del blocco in cui viene visualizzata la dichiarazione, iniziando con un proprio inizializzatore e comprendente ulteriori dichiaratori a destra nella dichiarazione di dichiarazione di variabile locale.

Nel tuo caso, case 2 è nello stesso blocco come case 1 e appare dopo che, anche se non sarà mai case 1 esecuzione ... quindi la variabile locale è di portata e disponibile per la scrittura nonostante si logicamente mai "eseguendo" la dichiarazione. (Una dichiarazione non è realmente "eseguibile" sebbene l'inizializzazione sia.)

Se si commenta l'assegnazione value = 2;, il compilatore sa ancora a quale variabile si sta riferendo, ma non si è passato attraverso alcun percorso di esecuzione che assegna ad esso un valore, motivo per cui si ottiene un errore come lo faresti quando proverai a leggere qualsiasi altra variabile locale non assegnata definitivamente.

Si consiglia vivamente di utilizzare lo non per utilizzare le variabili locali dichiarate in altri casi, poiché genera codice altamente confuso, come si è visto. Quando mi presento variabili locali in istruzioni switch (che cerco di fare raramente - casi dovrebbero essere molto brevi, idealmente) io di solito preferisco di introdurre un nuovo ambito:

case 1: { 
    int value = 1; 
    ... 
    break; 
} 
case 2: { 
    int value = 2; 
    ... 
    break; 
} 

Credo che questo sia più chiaro.

+8

+1 per "Una dichiarazione non è realmente" eseguibile "sebbene l'inizializzazione sia.". E grazie anche per i consigli Skeet. – namalfernandolk

18

partire http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block

dichiarazioni vengono elaborati in fase di compilazione e non dipendono dal flusso esecuzione del codice. Poiché lo value è dichiarato nell'ambito locale del blocco switch, è utilizzabile in qualsiasi punto del blocco da il punto della sua dichiarazione.

+0

perché questa risposta è in aumento? non risponde alla domanda, diversamente dalla risposta di paul o skeet ... –

+6

Lo fa. Quindi, +1, un centesimo, anche dalla mia parte. –

18

La variabile è stata dichiarata (come int), ma non inizializzata (assegnato un valore iniziale). Pensate della linea:

int value = 1; 

Come:

int value; 
value = 1; 

La parte int value dice al compilatore in fase di compilazione che avete una chiamata valore di una variabile, che è un int. La parte value = 1 lo inizializza, ma ciò accade in fase di esecuzione e non si verifica affatto se non si immette quel ramo dell'interruttore.

+0

+1 per la bella spiegazione della dichiarazione e dell'inizializzazione in fase di compilazione e runtime. – namalfernandolk