usar una tipo métodos metodos metodo las estaticos entre diferencia declarados cuando como clase bloque almacenan java static final

java - tipo - ¿En qué orden se ejecutan los bloques estáticos y las variables estáticas en una clase?



public static java (3)

Posible duplicado:
Inicialización de clases estáticas de Java

¿Por qué se actualiza la variable de cadena en el bloque de inicialización y no en el entero (aunque el bloque se escriba 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é? ¿Por qué no también para enteros? También lo he declarado como estático final


Aquí hay una respuesta corta y directa a tu pregunta ...

static Variable :

Las variables estáticas se ejecutan cuando la JVM carga la Class , y la Class se carga cuando se crea una instancia o se llama a su static method .

static Block or static Initializer Block :

el bloque de inicializador estático estático se inicializa antes de que la Class se ejemplifique 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 realizará 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 static null porque el Constant folding se aplica al tipo primitivo y no al objeto envoltorio, en su caso su entero ...


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

El procedimiento para inicializar C es el siguiente:

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

  • A continuación, ejecute los inicializadores de variable 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 de no compilación, no es un caso de "todas las variables" y luego de "todos los inicializadores estáticos" o viceversa, todos juntos, en orden textual. Así que 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 haciendo x o y final no afectaría esto aquí, ya que todavía no serían constantes en tiempo de compilació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 de tiempo de compilación, y cualquier uso de la misma básicamente está en línea. Además, el valor de la variable se asigna antes del resto de los inicializadores, como se indicó anteriormente.

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


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