Ci sono delle garanzie in JLS su ordine dei blocchi di inizializzazione esecuzione statici?
-
26-09-2019 - |
Domanda
Mi chiedo se è certo usare una costruzione del tipo:
private static final Map<String, String> engMessages;
private static final Map<String, String> rusMessages;
static {
engMessages = new HashMap<String, String> () {{
put ("msgname", "value");
}};
rusMessages = new HashMap<String, String> () {{
put ("msgname", "значение");
}};
}
private static Map<String, String> msgSource;
static {
msgSource = engMessages;
}
public static String msg (String msgName) {
return msgSource.get (msgName);
}
C'è una possibilità che avrò NullPointerException
causa blocco di inizializzazione msgSource
verrà eseguito prima del blocco che inizializza engMessages
?
(circa perché non faccio l'inizializzazione msgSource
alla fine di init superiore blocco:. Solo la questione di gusti, io farò in modo se la costruzione descritta non è affidabile)
Soluzione
Sì, statico initializer blocchi sono garantiti per eseguire in modo testuale.
Dalle JLS, sezione 12.4.1 :
L'intento è che un tipo di classe o interfaccia ha un insieme di inizializzatori che lo mettono in uno stato costante, e che questo stato è il primo stato che si osserva da altre classi. Le inizializzatori statici e inizializzatori variabile di classe vengono eseguiti in ordine testuale , e non può riferirsi a variabili di classe dichiarate nella classe le cui dichiarazioni comparire testualmente dopo l'uso, anche se queste variabili di classe sono di portata (§8.3 .3). Questa limitazione è progettato per rilevare, in fase di compilazione, inizializzazioni più circolari o comunque non validi.
E da 12.4 .2 :
Successivamente, eseguire sia le variabili inizializzatori classe e inizializzatori statici della classe oi inizializzatori campo dell'interfaccia, al fine testuale , come se fossero un unico blocco.
Personalmente, però, mi piacerebbe mettere tutte le dichiarazioni di variabili in partenza, e poi un unico statica inizializzatore blocco. Ritengo che per essere molto più facile da seguire.