reglas herramientas estatico codigo analisis java constructor static static-methods

java - herramientas - ¿Por qué se ejecuta el código estático de subclase?



reglas de analisis estatico de codigo (4)

He escrito el siguiente código y he creado el objeto para la súper clase.

class SuperClass{ static int a=2; static int b(){ return 2; } int c(){ return 2; } SuperClass(){ System.out.println("Super"); } static { System.out.println("super"); } } public class Sub extends SuperClass{ Sub(){ System.out.println("Sub"); } static { System.out.println("sub"); } static int b(){ return 3; } int c(){ return 3; } public static void main(String ax[]){ SuperClass f =new SuperClass(); System.out.println(f.c()); System.out.print(SuperClass.b()); } }

Cuando verifiqué la salida, es como sigue:

super sub Super 2 2

Sé que el bloque estático se ejecuta solo cuando el objeto de la clase se inicializa o se hace cualquier referencia estática. Pero aquí, no hice ninguno de estos para la clase Sub. entonces, ¿por qué veo "sub", es decir, la salida de bloque estático de subclase?


Sé que el bloque estático se ejecuta solo cuando el objeto de la clase se inicializa o se hace cualquier referencia estática. Pero aquí, no hice ninguno de estos para la clase Sub.

Su código no lo hace, pero para que se ejecute ese main , Sub debe cargarse. Así se ejecuta el inicializador estático para ello.

Por ejemplo, supongo que lo ejecutaste así:

java Sub

La herramienta java tiene que cargar Sub para llamar a Sub.main . Esa es la referencia estática (acceso, realmente) que hace que se ejecute el inicializador estático. (Si lo ejecutó en un IDE, el IDE realizará la parte de la herramienta java , pero el resultado es el mismo).

Así que aquí está lo que pasó:

  1. java activa la carga de Sub

  2. JVM tiene que cargar SuperClass para cargar Sub

  3. Así que vemos que sus inicializadores estáticos se ejecutan, en orden ( SuperClass , luego Sub ):

    super sub

  4. java herramienta java llama main

  5. Código en las main llamadas de new SuperClass :

    Super

  6. Código en llamadas main fc()

    2

  7. Código en las main llamadas SuperClass.b :

    2

Como Holger señala de manera útil, esto está cubierto por la especificación JVM en §5.5 - Inicialización y el §5.2 relacionado - Inicio de la máquina virtual Java :

La inicialización de una clase o interfaz consiste en ejecutar su método de inicialización de clase o interfaz (§2.9).

Una clase o interfaz C puede inicializarse solo como resultado de:

  • ...

  • Si C es una clase, la inicialización de una de sus subclases.

  • Si C es una clase, su designación como la clase inicial en el inicio de la Máquina Virtual Java (§5.2).

El punto de bala segundo a último cubre SuperClass y el último punto de bala cubre Sub .


Al llamar a main , se llama a todos los inicializadores estáticos, primero en la súper clase, luego en la subclase.

Eso explica la salida que observas.


Debido a que su método main() es miembro de Sub , esa clase debe cargarse para que su programa se ejecute.


Los bloques estáticos se ejecutan cuando se carga la clase. Por lo general, eso se debe a que se llama un constructor o miembro estático. en este caso, es porque ejecutó el método principal (un miembro estático).

Notas al margen:

  1. otro caso de borde está llamando a Class.forName (className) para cargar una clase.
  2. También puede observar que la clase base se carga antes de la subclase.