java - component - setlayout jpanel
El inicializador estático se ejecuta después del constructor, ¿por qué? (1)
static B b = new B();
es antes
static {
System.out.println("A static block");
}
Por lo tanto, es necesario que la instancia B se inicialice antes de imprimir "A static block"
.
Y la inicialización de la clase B significa que necesita crear una instancia A. Así que no hay forma de que se imprima "Un bloque estático" antes de que se construya la instancia de A.
Sí, la inicialización estática de A se inicia antes de que se inicie el constructor, pero, aparte del interbloqueo, no habría otra solución para la secuencia que necesita.
Tenga en cuenta la advertencia en la especificación :
Debido a que el lenguaje de programación Java es multiproceso, la inicialización de una clase o interfaz requiere una sincronización cuidadosa, ya que es posible que otros subprocesos estén intentando inicializar la misma clase o interfaz al mismo tiempo. También existe la posibilidad de que la inicialización de una clase o interfaz pueda solicitarse recursivamente como parte de la inicialización de esa clase o interfaz; por ejemplo, un inicializador de variable en la clase A podría invocar un método de una clase B no relacionada, que a su vez podría invocar un método de la clase A. La implementación de la máquina virtual Java es responsable de cuidar la sincronización y la inicialización recursiva mediante el uso de siguiente procedimiento [el documento continúa con el procedimiento completo]
Una buena práctica, en Java como en otros lenguajes, es básicamente evitar las dependencias cíclicas ya que su resolución puede ser muy difícil de predecir.
Tengo 2 clases:
Clase A:
public class A {
static B b = new B();
static {
System.out.println("A static block");
}
public A() {
System.out.println("A constructor");
}
}
Clase B:
public class B {
static {
System.out.println("B static block");
new A();
}
public B() {
System.out.println("B constructor");
}
}
Creo una clase principal que crea una nueva A:
public class Main {
public static void main(String[] args) {
new A();
}
}
La salida que obtengo es:
B static block
A constructor
B constructor
A static block
A constructor
Como puede ver, el constructor de A se invoca antes de su inicializador estático.
Entiendo que tiene algo que ver con la dependencia cíclica que creé, pero tenía la impresión de que el inicializador estático siempre debería ejecutarse antes que el constructor.
¿Cuál es la razón para que esto suceda (técnicamente en la implementación de java)?
¿Se recomienda evitar todos los inicializadores estáticos?