¿Hay garantías de JLS sobre el orden de los bloques de inicialización ejecución estática?
-
26-09-2019 - |
Pregunta
Me pregunto si es confiable utilizar una construcción como:
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);
}
¿Hay una posibilidad de que voy a conseguir porque NullPointerException
bloque msgSource
primero se ejecutará antes del bloque que inicializa engMessages
?
(acerca de por qué no lo hago inicialización msgSource
al final del bloque init superior:. Sólo la cuestión de gusto; lo haré por lo que si la construcción descrita no es fiable)
Solución
Sí, estática inicializador bloques están garantizados para ejecutar en el orden textual.
A partir de los JLS, sección 12.4.1 :
La intención es que una clase o tipo de interfaz que tiene un conjunto de inicializadores que lo ponen en un estado coherente, y que este estado es el primer estado que se observa por otras clases. Los inicializadores estáticos y variables inicializadores de clase se ejecutan en orden textual , y no puede referirse a variables de clase declarada en la clase cuyas declaraciones aparecen textualmente después del uso, a pesar de que estas variables de clase son de alcance (§ 8.3 0.3). Esta restricción está diseñado para detectar, en tiempo de compilación, inicializaciones más circulares o de otra manera con formato incorrecto.
Y a partir de 12.4 0,2 :
A continuación, ejecute cualquiera de los inicializadores de variables de clase y inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en el orden textual , como si fueran un solo bloque.
Personalmente, sin embargo, me gustaría poner todas las declaraciones de variables al comienzo, y luego una sola estática inicializador bloque. Considero que para ser mucho más fácil de seguir.