¿en qué orden se ejecutan bloques estáticos y variables estáticas en una clase?

Posible duplicado:
Inicialización de clase estática de Java

¿Por qué la variable de cadena se actualiza en el bloque de inicialización y no en el número entero (aunque el bloque se escribe primero)?

class NewClass { static { System.out.println(NewClass.string+" "+NewClass.integer); } final static String string="static"; final static Integer integer=1; public static void main(String [] args)//throws Exception { } } 

Mi salida es

 static null 

PD: También noté que la inicialización de la variable de cadena ocurre antes del bloque solo cuando inserto el modificador final. ¿Por qué es eso? ¿Por qué no también para enteros? Lo he declarado como estático final también

De la sección 12.4.2 del JLS, recortado apropiadamente:

El procedimiento para inicializar C es el siguiente:

  • Luego, inicialice las variables de clase finales y los campos de las interfaces cuyos valores son expresiones constantes en tiempo de comstackción (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

  • A continuación, ejecute los inicializadores de variables de clase y los inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en orden textual, como si fueran un solo bloque.

Por lo tanto, para las constantes de tiempo no de comstackción, no es un caso de “todas las variables” y luego “todos los inicializadores estáticos” o viceversa; están todas juntas, en orden textual. Entonces si tuvieras:

 static int x = method("x"); static { System.out.println("init 1"); } static int y = method("y"); static { System.out.println("init 2"); } static int method(String name) { System.out.println(name); return 0; } 

Entonces la salida sería:

 x init 1 y init 2 

Incluso hacer x o y final no afectaría esto aquí, ya que todavía no serían constantes de tiempo de comstackción.

PD: También noté que la inicialización de la variable de cadena ocurre antes del bloque solo cuando inserto el modificador final.

En ese punto, es una constante en tiempo de comstackción, y cualquier uso de ella básicamente está en línea. Además, el valor de la variable se asigna antes que el rest de los inicializadores, como se indicó anteriormente.

La sección 15.28 del JLS define constantes de tiempo de comstackción: incluye todos los valores primitivos y String , pero no los tipos de envoltura como Integer .

Aquí hay una respuesta breve y directa a su pregunta …

static Variable :

Las variables estáticas se ejecutan cuando la JVM carga la Class y la Class se carga cuando se ha instanciado o se está llamando a su static method .

static Block or static Initializer Block :

El bloque de inicializador estático estático se inicializa antes de que se genere una instancia de la Class o antes de static method se llame a su static method , e incluso antes de que se use su static variable .

///////// Pieza editada /////////

 class NewClass { final static String string = "static"; final static Integer integer = 1; static { System.out.println(NewClas.string + " " + NewClas.integer); } public static void main(String [] args) { // throws Exception new NewClas(); } } 

Lo anterior imprimirá static 1 .

La razón es que la JVM hará el proceso de optimización conocido como Constant folding , haciendo un cálculo previo de las variables constantes.

Además, en su caso, el resultado fue una causa static null Constant folding se aplica al tipo Primitivo y no al Objeto Contenedor, en su caso es un Entero …

Se inicializan en el orden dado (campos y bloques estáticos), es por eso que el valor impreso es null , no se asignó nada a los campos estáticos que se definen después del bloque estático.