2013-06-15 16 views
5

Nota: sono ben consapevole che l'inizializzazione risolve il problema; Ho appena pensato che il compilatore avrebbe seguito il percorso di esecuzione e visto che foo sarebbe stato effettivamente inizializzato nel punto in cui suggerisce che "potrebbe" non esserlo.Comportamento imprevisto con l'inizializzazione Java

La mia ipotesi iniziale sarebbe che se la lunghezza non fosse mai finita 3, non avrei mai avuto bisogno di allocare memoria perché venisse usata.

Questo non verrà mai utilizzato nella produzione, sono semplicemente curiosi

vedere l'esempio seguente: -

List<String> foo; 

int length = 5; 

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

if (length > 4) 
{ 
    foo.add("bar"); 
} 

Perché questa causa il seguente da visualizzare?

La foo variabile locale non può essere stato inizializzato

Sicuramente seguendo i rami, non v'è mai un caso in cui foo non è inizializzato. So che se dovessi fare: -

List<String> foo = null; 

non ci sarebbero problemi di compilazione, ma perché ho bisogno di fare questo?

+2

@down voter, potresti almeno fornire un motivo? – chrisw

risposta

5

Le variabili locali devono essere inizializzate prima di utilizzarle altrove perché non verranno inizializzate di default. Cosa succede se lo if() non è true?

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

Il compilatore non può sapere se la condizione sarà vera.

Una variabile locale (§14.4, §14.13) occorre fornire espressamente un valore prima del suo utilizzo, da uno inizializzazione (§14.4) o cessione (§15.26), in un modo che può essere verificata da il compilatore utilizzando le regole per l'assegnazione definitiva

come @jlordo rilevare rendendo il length come final risolverà l'errore di compilazione, perché al momento della compilazione in sé il compilatore sa che il valore di length sarà sempre 5 e da qui la condizione length>3 i s sempre true quindi la variabile locale verrà inizializzata.

+1

+1 Questo è il punto - "in un modo che può essere verificato dal compilatore". In linea di principio, il compilatore potrebbe dire che foo è sempre assegnato prima che venga usato qui, ma non lo fa. –

+0

+1 Quella citazione chiarisce chiaramente perché l'errore si verifica insieme con la tua spiegazione – chrisw

5

Il compilatore non può essere sicuro di essere il primo se il blocco verrà inserito. Se così non fosse, allora foo rimarrà non inizializzato. Non è possibile chiamare add su una variabile non inizializzata ,. Puoi aiutare il compilatore rendendo length finale. Il compilatore saprà quindi che verrà eseguito il primo blocco if.

final int length = 5; 
+0

@ ÓscarLópez: copia codice OP, imposta 'length' finale e l'errore del compilatore scompare;) – jlordo

+1

@Oscar, final consente di compilare il codice senza errori; se questa è la cosa giusta da fare o no sarebbe per un'altra discussione – chrisw

+0

@ chrisw69: Esattamente. Sto solo dicendo che questo eliminerà l'errore del compilatore. Non sto dicendo che è un buon stile. – jlordo

1

Questo succede perché foo è inizializzato in un ramo. Quindi il compilatore non è sicuro se foo verrà inizializzato o meno.

2

Poiché un'istanza locale non è inizializzata per impostazione predefinita, diversamente dalle istanze di classe o oggetto.

Dal Java Language Specification:

Una variabile locale (§14.4, §14.14) occorre fornire espressamente un valore prima del suo utilizzo, da uno inizializzazione (§14.4) o cessione (§15.26), in modo che può essere verificato dal compilatore utilizzando le regole per l'assegnazione definitiva (§16).

I valori predefiniti:

For type byte, the default value is zero, that is, the value of (byte)0. 
For type short, the default value is zero, that is, the value of (short)0. 
For type int, the default value is zero, that is, 0. 
For type long, the default value is zero, that is, 0L. 
For type float, the default value is positive zero, that is, 0.0f. 
For type double, the default value is positive zero, that is, 0.0d. 
For type char, the default value is the null character, that is, '\u0000'. 
For type boolean, the default value is false. 
For all reference types (§4.3), the default value is null. 
1

istanza e di classe variabili sono inizializzate a null o 0 valori. Ma le variabili locali non lo sono. Quindi è necessario avere per inizializzare le variabili locali prima di utilizzarlo.

Problemi correlati