variable usar sirve que para metodos metodo inicializacion estática estaticos estatico definicion cuando clase bloque java class static initialization

java - usar - ¿Por qué.class no invoca el bloque estático en una Clase?



public static java (2)

Este es el código que tengo:

public class StupidClass { static { System.out.println("Stupid class loaded!"); } }

Y las pruebas que tengo, que ejecuto por separado .

import org.junit.Test; public class StupidTest { @Test public void foo() throws ClassNotFoundException { final Class<?> stupidClass = Class.forName("StupidClass"); System.out.println(stupidClass.getSimpleName()); } @Test public void bar() throws ClassNotFoundException { final Class<StupidClass> stupidClassClass = StupidClass.class; System.out.println(stupidClassClass.getSimpleName()); } }

Cuando ejecuto test foo veré:

Stupid class loaded! StupidClass

Pero cuando ejecuto la barra de prueba , todo lo que veo es:

StupidClass

Citando de this página ...

La máquina virtual Java crea automáticamente los objetos de clase a medida que las clases se cargan y mediante llamadas al método defineClass en el cargador de clases.

Entonces, entiendo que, en la barra de prueba, se carga la clase Estúpido, de lo contrario, ¿habría visto un valor nulo, supongo? Entonces, el objeto Class se crea porque la clase misma se carga.

Y ahora citando desde this página

Los bloques de inicialización estática se ejecutan cuando el JVM (cargador de clases, para ser específico) carga StaticClass (que ocurre la primera vez que se hace referencia en el código).

Así que espero ver la "¡Estúpida clase cargada!" texto en la barra de prueba también, pero no lo soy.

También citando de Thinking in Java

Cada una de las clases Candy, Gum y Cookie tiene una cláusula estática que se ejecuta cuando la clase se carga por primera vez.

lo cual no es muy exacto parece ...

¿Qué me estoy perdiendo?


Los bloques de inicialización estática se ejecutan cuando el JVM (cargador de clases, para ser específico) carga StaticClass (que ocurre la primera vez que se hace referencia en el código).

La cita anterior es simplemente errónea, pero es solo una instancia de una idea errónea muy extendida.

  1. La clase no se inicializa cuando se está cargando, sino cuando se hace referencia por primera vez a un miembro de clase estático. Esto se rige precisamente por la specification .

  2. La carga de la clase no ocurre cuando se hace referencia a la clase por primera vez, sino en un punto dependiente de la implementación.

  3. El último momento en que se debe cargar la clase es cuando se hace referencia a la clase, que no es lo mismo que hacer referencia a un miembro de la clase.

Class.forName inicializa la clase de forma predeterminada, pero tiene la opción de llamar a una sobrecarga que toma una boolean initialize y proporciona false . Obtendrá la clase cargada sin inicializar.


La carga de clases y la inicialización son 2 cosas diferentes. Una clase puede cargarse pero no inicializarse hasta que sea realmente necesaria. Los inicializadores estáticos se ejecutan solo cuando una clase se está inicializando <> NO cargada, "inicializada"

En el primer caso, está cargando e inicializando una clase cuando usa class.forName() , por eso se ejecutan los inicializadores estáticos y, por lo tanto, ve "Stupid class loaded!" como salida En el segundo caso, solo está asignando una referencia de la clase, la clase está cargada (use java -verbose: class para ver qué clases están cargadas) pero en realidad no la está inicializando (o para ser más precisos, no haciendo cualquier cosa que obligue a los inicializadores a ejecutarse). ¡Por lo tanto, no verá la salida como una Stupid class loaded! . Intente hacer algo como llamar a newInstance() en la clase, debería forzar la inicialización de la clase y debería ver la Stupid class loaded!

Mi código :

public class CheckPalindrome { public static void main(String[] args) { Class<Test> t = Test.class; } } // class being loaded class Test { static { System.out.println("aaa"); } }

Clases que están cargadas

... [Loaded Test from file:/Workspaces/SampleTest/Java8/bin/] ...

^ - Esto muestra que la clase se carga pero no se inicializa.