2013-05-07 12 views
6

Ho notato qualcosa in inizializzatori statici che potrebbe essere un bug nel javac. Ho costruito uno scenario in cui posso assegnare a una variabile un valore ma non leggere quel valore indietro.Errore statico di inizializzazione se inserito prima della dichiarazione

I due esempi riportati di seguito, il primo compila bene, il secondo ottiene un errore quando si tenta di leggere un valore da tmp, ma per qualche motivo l'assegnazione di un valore a tmp è consentita. Potrei capire se non può né leggere né scrivere sulla variabile poiché tmp viene dichiarato dopo l'inizializzatore statico, ma un errore su uno solo di quelli non ha senso per me.

//Compiles Successfully: 
public class Script 
{ 
    public static Object tmp; 
    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 

} 

//error only on the read but not the assignment 
public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 
    public static Object tmp; 
} 

per enfatizzare ulteriormente il punto, questo viene compilato correttamente.

public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
    } 
    public static Object tmp; 
} 
+0

Credo [una risposta a una domanda simile] [1] risponde a questa domanda meglio di quanto possa. È un comportamento strano ma non un bug. Sta facendo quello che dovrebbe fare. [1]: http://stackoverflow.com/a/10035928/348975 – emory

+0

Non sono sicuro che lo faccia, gli inizializzatori statici sono lì per inizializzare le variabili dal loro valore predefinito. che vuol dire statico int v = 1; è equivalente a static v v; static {v = 1;} –

+0

@Dukeling Ho scritto il mio commento come risposta e StackOverflow ha determinato che la mia risposta è stata banale (penso che sia troppo corta) e l'ho convertita automagicamente in un commento, ma evidentemente ha cambiato i link. – emory

risposta

3

Sembra questo è definito nelle specifiche (vedere JLS 8.3.2.3):

La dichiarazione dell'utente deve comparire testualmente prima che sia utilizzato solo se l'elemento è un'istanza (rispettivamente statico) campo di una classe o un'interfaccia C e tutte le seguenti condizioni:

  • L'utilizzo avviene in un'istanza (rispettivamente statico) Vari inizializzatore di C o in un inizializzatore istanza (rispettivamente statico)
    di C.

  • L'utilizzo non è sul lato sinistro di un compito.

  • L'utilizzo avviene tramite un nome semplice.

  • C è la classe più interna o l'interfaccia che racchiude l'utilizzo.

Quindi, se l'utilizzo è sul lato sinistro di un'assegnazione, allora è legale, dal momento che la seconda non regge più.

+0

Ok, compro che fa parte delle specifiche, tuttavia sembra una cosa molto strana da specificare –

+0

A volte penso che Java abbia bisogno di più di una semplice specifica, ma anche un altro libro che spiega le decisioni che prende. Spero che qualcuno possa gettare più luce su questo, ma le specifiche sono le migliori che posso trovare. –

Problemi correlati