2010-08-17 23 views
97

¿Cuándo se inicializan los campos estáticos? Si nunca instanciar una clase, pero tengo acceso a un campo estático, ¿TODOS los bloques estáticos y los métodos estáticos privados se usan para crear instancias de campos estáticos privados llamados (en orden) en ese instante?¿Cuándo ocurre la inicialización de clase estática?

¿Qué pasa si llamo a un método estático? ¿También ejecuta todos los bloques estáticos? Antes del método?

+0

similares para los bloques inicializador estático: http://stackoverflow.com/questions/ 2007666/in-what-order-do-static-initializer-blocks-in-java-run –

Respuesta

138

inicialización estática de una clase normalmente ocurre inmediatamente antes de la primera vez que uno de los siguientes eventos:

  • se crea una instancia de la clase,
  • se invoca un método estático de la clase,
  • se asigna un campo estático de la clase,
  • se usa un campo estático no constante o
  • para una clase de nivel superior, una declaración de afirmación anidada léxicamente dentro de la clase es ejecutado.

Ver JLS 12.4.1.

También es posible forzar una clase para inicializar (si aún no lo ha inicializado) mediante el uso de Class.forName(fqn, true, classLoader) o la forma corta Class.forName(fqn)

+0

Enfriar gracias por la información adicional. –

+5

+1 para dar la referencia de JLS – Moshe

+4

También tenga en cuenta que la forma más corta 'Class.forName (className)' también fuerza la inicialización porque es equivalente a 'Class.forName (className, true, currentLoader)'. – user113215

1

Sí, todos los inicializadores estáticos se ejecutan antes de acceder a la clase por primera vez. Si fuera de otra manera, lo llamaría un error.

+0

Hay formas de referirse a una clase sin inicializarla. –

11

Los campos estáticos se inicializan durante la "fase" initialization de la carga de clases (carga, enlace e inicialización) que incluye inicializadores estáticos e inicializaciones de sus campos estáticos. Los inicializadores estáticos se ejecutan en un orden textual como se define en la clase.

Considere el ejemplo:

public class Test { 

    static String sayHello() { 
     return a; 
    } 

    static String b = sayHello(); // a static method is called to assign value to b. 
           // but its a has not been initialized yet. 

    static String a = "hello"; 

    static String c = sayHello(); // assignes "hello" to variable c 

    public static void main(String[] arg) throws Throwable { 
     System.out.println(Test.b); // prints null 
     System.out.println(Test.sayHello()); // prints "hello" 
    } 
} 

El Test.b imprime null porque cuando el sayHello se llamó en su alcance estática, la variable estática a no se ha inicializado.

+6

Estrictamente hablando, la inicialización no es una "fase" de carga de clase. De hecho, algunas clases * pueden * cargarse pero nunca inicializarse si la aplicación no las usa. –

+0

@Stephen C Tienes razón, lo usé por falta de un término mejor, tal vez lo cite. – naikus

+0

@StephenC significa que mientras se realiza la carga Clase, asigna memoria a las variables estáticas (& métodos) pero esas variables estáticas no se inicializan con los valores proporcionados en el código? porque aquí parece que cuando b-> sayHello() -> a, 'a' está en la memoria pero aún no tiene asignado valor. –

Cuestiones relacionadas