2012-01-18 15 views
13

Ho appena fatto una piccola modifica al codice per silenziare un avviso FindBugs che richiedeva lo spostamento di un codice in una classe interna anonima. Per accedere ad alcune variabili, ho dovuto dichiararle come final. Quindi questo è il frammento di codice dopo il cambio:Dichiarare le variabili locali come definitive senza inizializzatore e assegnando in if-statement

final File[] libPath; // libPath is final but assignment takes place later 
if (libraryPath != null) { 
    libPath = pathToFiles(libraryPath); 
} else { 
    libPath = new File[0]; 
} 

Questo compila bene con la lingua impostata su Java 6 in Eclipse corrente (versione 3.7.1). Tuttavia sono abbastanza sicuro che questo ha dato un errore in alcune versioni precedenti. Sembra che il compilatore accetti questo costrutto quando può determinare che ci sarà.

La mia domanda è: questo è legale in Java 6 o è qualcosa che ora funziona a causa di un effetto collaterale del supporto Java 7 che viene aggiunto a Eclipse 3.7.1? Abbiamo visto tali effetti collaterali con un certo uso di generici che funzionano in 3.7.1 ma non sono stati compilati in 3.7.0.

risposta

8

Questo era consentito e funzionava bene da Java 1.1 e non ti porterà nei guai con altri compilatori o IDE.

È un comportamento standard in Java ed è stato formalmente specificato nello Java Language Specification 2nd Edition.

+0

Dalle molte risposte corrette che indicano le specifiche della lingua, accetterò questo dato che tu eri il primo a rispondere. – Axel

0

Va bene. La variabile non ha un valore e viene assegnata una sola volta. Fallirebbe se gli avessi dato inizialmente un valore null.

0

mi piacerebbe consigliamo vivamente di utilizzare questo codice invece:

final File[] libPath = ibraryPath == null ? new File[0] : pathToFiles(libraryPath); 

Questo non dipende da qualsiasi versione del compilatore, ma è al 100% sostenuta Java con un significato chiaro.

+1

Alcuni direbbero che è anche più complicato da leggere;) – ShiDoiSi

+0

È una questione di gusti, forse. Ma io lo preferisco, perché le espressioni rimangono espressioni e non sono convertite inutilmente in dichiarazioni. Questo è anche un costrutto linguistico che è presente in quasi tutte le lingue almeno da C, quindi chi non può leggerlo dovrebbe forse lasciare il lavoro piuttosto prima che dopo. – Ingo

13

questo è ok. si chiama vuoto finale

citazione da wiki:

Una variabile finale può essere inizializzato solo una volta, sia attraverso un inizializzazione o di un'istruzione di assegnazione. Non è necessario inizializzarlo allo il punto di dichiarazione: si tratta di una variabile "vuota finale". A alla fine di ogni costruttore della classe in cui è dichiarata, una variabile di istanza finale vuota di una classe deve essere assegnata definitivamente a ; analogamente, una variabile statica finale vuota deve essere assegnata definitivamente a in un inizializzatore statico della classe in cui è dichiarata: in caso contrario, si verifica un errore in fase di compilazione in entrambi i casi. [4] (Nota: se la variabile è un riferimento, questo significa che la variabile non può essere ri-bound per fare riferimento a un altro oggetto, ma l'oggetto che riferimenti è ancora mutevole, se in origine era mutevole..)

vuoto finale

Il vuoto finale, che è stato introdotto in Java 1.1, è una variabile finale la cui dichiarazione manca un inizializzatore. [5] [6] Una finale vuota può essere assegnata una sola volta a e deve essere annullata quando si verifica un incarico.Nell'ordine per fare ciò, un compilatore Java esegue un'analisi del flusso per garantire che, per ogni assegnazione a una variabile finale vuota, la variabile sia definitivamente non assegnata prima dell'assegnazione; altrimenti si verifica un errore in fase di compilazione. [7]

In generale, un compilatore Java assicurerà che la finale vuoto non è utilizzato fino a quando viene assegnato un valore e che una volta assegnato un valore, la variabile ora finale non può essere riassegnato un altro valore. [8]

link: http://en.wikipedia.org/wiki/Final_%28Java%29

+1

Wow, pensavo di conoscere almeno tutta la sintassi di Java, grazie per aver spiegato questa nuova ruga. – ArtB

1

Java Language Specification contiene un intero capitolo dedicato a questo comportamento (Chapter 16 Definite Assignment).

Questo comportamento è completamente definito, in modo che io pensi di interpretare male qualcosa quando dici che era usato per produrre un errore nelle versioni precedenti.

0

Sì, questo funzionerà ed è sicuro da usare in tutte le versioni java che ho visto (1.3+).

finale significa che non è possibile modificare il valore dell'oggetto una volta che è stato inizializzato, se è stato inserito un valore null in seguito alla dichiarazione che si sarebbe rotto.

Problemi correlati