variable usar sirve que para metodos metodo inicializadores estaticos cuando clase bloques java static-initializer

usar - para que sirve static en java



¿En qué orden se ejecutan los bloques de inicializador estático/instancia en Java? (7)

Supongamos que un proyecto contiene varias clases, cada una de las cuales tiene un bloque de inicializador estático. ¿En qué orden se ejecutan esos bloques? Sé que dentro de una clase, dichos bloques se ejecutan en el orden en que aparecen en el código. He leído que es igual en todas las clases, pero un código de muestra que escribí no está de acuerdo con eso. Usé este código:

package pkg; public class LoadTest { public static void main(String[] args) { System.out.println("START"); new Child(); System.out.println("END"); } } class Parent extends Grandparent { // Instance init block { System.out.println("instance - parent"); } // Constructor public Parent() { System.out.println("constructor - parent"); } // Static init block static { System.out.println("static - parent"); } } class Grandparent { // Static init block static { System.out.println("static - grandparent"); } // Instance init block { System.out.println("instance - grandparent"); } // Constructor public Grandparent() { System.out.println("constructor - grandparent"); } } class Child extends Parent { // Constructor public Child() { System.out.println("constructor - child"); } // Static init block static { System.out.println("static - child"); } // Instance init block { System.out.println("instance - child"); } }

y obtuve esta salida:

COMIENZO
estático - abuelo
estático - padre
estático - niño
instancia - abuelo
constructor - abuelo
instancia - padre
constructor - padre
instancia - niño
constructor - niño
FIN

La respuesta obvia es que los bloques de los padres se ejecutan antes que los de sus hijos, pero eso podría ser solo una coincidencia y no ayuda si dos clases no están en la misma jerarquía.

EDITAR:

Modifiqué mi código de ejemplo al anexarlo a LoadTest.java:

class IAmAClassThatIsNeverUsed { // Constructor public IAmAClassThatIsNeverUsed() { System.out.println("constructor - IAACTINU"); } // Instance init block { System.out.println("instance - IAACTINU"); } // Static init block static { System.out.println("static - IAACTINU"); } }

Tal como lo implica el nombre de la clase, nunca hice referencia a la nueva clase en ningún lado. El nuevo programa produjo el mismo resultado que el anterior.


El inicializador estático de una clase se ejecuta cuando se accede por primera vez a la clase, ya sea para crear una instancia o para acceder a un método o campo estático.

Entonces, para múltiples clases, esto depende totalmente del código que se ejecuta para hacer que esas clases se carguen.


Hay un caso en el que no se llamará un bloque estático.

class Super { public static int i=10; } class Sub extends Super { static { system.out.println("Static block called"); } } class Test { public static void main (String [] args) { system.out.println(Sub.i); } }

El código anterior muestra 10


La inicialización de una clase consiste en ejecutar sus inicializadores estáticos y los inicializadores para los campos estáticos (variables de clase) declarados en la clase.

La inicialización de una interfaz consiste en ejecutar los inicializadores para los campos (constantes) declarados en la interfaz.

Antes de inicializar una clase, su superclase directa debe inicializarse, pero las interfaces implementadas por la clase no se inicializan. De forma similar, las superinterfaces de una interfaz no se inicializan antes de que se inicialice la interfaz.


Las respuestas de Keith y Chris son geniales, solo estoy agregando más detalles para mi pregunta específica.

Los bloques de init estáticos se ejecutan en el orden en que se inicializan sus clases. Entonces, ¿qué orden es eso? Según JLS 12.4.1:

Una clase o interfaz de tipo T se inicializará inmediatamente antes de la primera aparición de cualquiera de los siguientes:

  • T es una clase y se crea una instancia de T.
  • T es una clase y se invoca un método estático declarado por T.
  • Se asigna un campo estático declarado por T.
  • Se utiliza un campo estático declarado por T y el campo no es una variable constante (§4.12.4).
  • T es una clase de nivel superior, y se ejecuta una declaración de afirmación (§14.10) léxicamente anidada dentro de T.

La invocación de ciertos métodos reflectantes en la clase Class y en el paquete java.lang.reflect también provoca la inicialización de la clase o la interfaz. Una clase o interfaz no se inicializará bajo ninguna otra circunstancia.

Para ilustrar, aquí hay un recorrido de lo que está sucediendo en el ejemplo:

  1. Entrar en principal
  2. Imprimir "START"
  3. Intento de crear la primera instancia de Child, que requiere la inicialización de Child
  4. Intentar inicializar el niño provoca la inicialización del padre
  5. Intentar inicializar el padre provoca la inicialización de Abuelo
  6. Al inicio de la inicialización de Grandparent, se ejecuta el bloque de inicialización estático de Grandparent.
  7. Técnicamente, Object tiene la última palabra en la cadena de inicialización en virtud de ser el padre de los abuelos, pero no tiene nada que aportar
  8. Después de que finaliza el bloque de inicialización estático de Grandparent, el programa vuelve al bloque de inicialización estático de Parent.
  9. Después de que finaliza el bloque de inicialización estático de Parent, el programa vuelve al bloque de inicialización estático de Child
  10. En este punto, Child se inicializa, por lo que su constructor puede proceder
  11. Como nunca se hace referencia a IAmAClassThatIsNeverUsed, ninguno de sus códigos se ejecuta, incluidos los bloques de inicializadores estáticos.
  12. El resto de este tutorial no se refiere a inicializadores estáticos y se incluye solo para completar
  13. El constructor de Child llama implícitamente a super () (es decir, el constructor de Parent)
  14. El constructor de Parent llama implícitamente a super () (es decir, el constructor de Grandparent)
  15. El constructor de Grandparent hace lo mismo, lo que no tiene ningún efecto (nuevamente, Object no tiene nada que aportar)
  16. Inmediatamente después de la llamada del constructor de Grandparent a super (), aparece el bloque de inicialización de la instancia de Grandparent.
  17. El resto del constructor del constructor de Grandparent se ejecuta y el constructor finaliza
  18. El programa recae en el constructor de Parent, inmediatamente después de que se resuelva su llamada a super () (es decir, el constructor de Grandparent)
  19. Como se indicó anteriormente, el inicializador de instancias de Parent hace lo suyo y su constructor termina
  20. Del mismo modo, el programa regresa y completa el constructor de Child
  21. En este punto, el objeto ha sido instanciado
  22. Imprimir "END"
  23. Terminar normalmente

Puede tener múltiples inicializadores estáticos y de instancia en la misma clase, por lo tanto,

  • Los inicializadores estáticos se llaman en el orden textual en que se declaran (desde 12.4.2 )
  • Los inicializadores de instancias se llaman en el orden textual en que se declaran (desde 12.5 )

Cada uno se ejecuta como si fuera un solo bloque.


Vea la sección 12.4 y 12.5 de la versión 8 de JLS , entran en detalles sangrientos sobre todo esto (12.4 para estático y 12.5 para variables de instancia).

Para la inicialización estática (sección 12.4):

Una clase o interfaz de tipo T se inicializará inmediatamente antes de la primera aparición de cualquiera de los siguientes:

  • T es una clase y se crea una instancia de T.
  • T es una clase y se invoca un método estático declarado por T.
  • Se asigna un campo estático declarado por T.
  • Se utiliza un campo estático declarado por T y el campo no es una variable constante (§4.12.4).
  • T es una clase de nivel superior (§7.6) y se ejecuta una declaración de afirmación (§14.10) léxicamente anidada dentro de T (§8.1.3).

(y varias cláusulas de palabra comadreja)


http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

gentilmente revise la documentación de Java.

a continuación, se menciona claramente, no importa cómo pueden bloques estáticos allí se ejecutarán como un solo bloque en el orden en que aparecen

Asi que,

Mi comprensión aquí es que java está buscando tu código como

static{ i=1; i=2; }

static int i;

es por eso que estás obteniendo la salida 2

Espero que esto sea útil