2009-11-19 11 views
6

Imagine una clase Java que tiene la mayoría de las características que puede encontrar en una clase. Por ejemplo: hereda de otra clase, implementa un par de interfaces, incluye algunas constantes "estáticas finales", algunas constantes finales, algunas variables estáticas, variables de instancia, un bloque estático, un bloque de código sin nombre (solo código en {}), constructores, métodos, etc.¿En qué orden se inicializan las diferentes partes de una clase cuando se carga una clase en la JVM?

Cuando la clase en cuestión se carga en la JVM por primera vez, ¿en qué orden se inicializan o cargan las diversas partes de la clase en la JVM? ¿Cómo se ve la pila de llamadas en la JVM para la carga? Supongamos que solo hay un cargador de clases trabajando aquí.

Esto está volviendo a lo básico/interno absoluto de Java, pero no he podido encontrar un buen artículo que explique la secuencia correcta.

Respuesta

1

¿Qué tal el JLS, específicamente la sección 12.4?

+0

real smooth ... :) ¡deseo tener el término de búsqueda de Google correcto para llegar al JLS! también me di cuenta de que podría haber podido ejecutar esto a través del depurador de eclipse ... :( – Thimmayya

3

Este podría ser descrito en la sección 2.17.4 of the JVMS 5.0/6

2.17.4 Inicialización

Inicialización de una clase consta de:

  • la ejecución de sus inicializadores estáticos (§2.11) y
  • los inicializadores para campos estáticos (§2.9.2) declarados en la clase.

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

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

un tipo de clase o interfaz T se inicializará inmediatamente antes de una de las siguientes situaciones:

  • T es una clase y se crea una instancia de T.
  • T es una clase y se invoca un método estático de T.
  • Se utiliza o asigna un campo estático no constante de T. Un campo constante es aquel que es (explícita o implícitamente) tanto final como estático, y que se inicializa con el valor de una expresión constante en tiempo de compilación. Una referencia a dicho campo debe resolverse en tiempo de compilación a una copia del valor constante de tiempo de compilación, por lo que los usos de dicho campo nunca causan inicialización.

La invocación de ciertos métodos en clases de biblioteca (§3.12) también provoca la inicialización de clase o interfaz. Consulte las especificaciones de la biblioteca de clases de la plataforma Java 2 (por ejemplo, clase Class y paquete java.lang.reflect) para obtener más información.

La intención aquí es que un tipo tenga un conjunto de inicializadores que lo coloque en un estado consistente y que este estado sea el primer estado observado por otras clases. Los inicializadores estáticos y los inicializadores de variables de clase se ejecutan en orden textual y no pueden referirse a las variables de clase declaradas en la clase cuyas declaraciones aparecen textualmente después del uso, incluso aunque estas variables de clase estén dentro del alcance.Esta restricción está diseñada para detectar, en tiempo de compilación, la mayoría de las inicializaciones circulares o malformadas.

Antes de inicializar una clase o interfaz, su superclase se inicializa, si no se ha inicializado previamente.


La versión actualizada de Initialization in JVMS 8 is in Chapter 5.5

Inicialización de una clase o interfaz consiste en la ejecución de su método de inicialización clase o interfaz (§2.9).

una clase o interfaz se puede inicializar sólo como resultado de:

  • La ejecución de cualquiera de las instrucciones de Java Virtual Machine new, getstatic, putstatic o invokestatic que hace referencia a la clase o interfaz (§new , §getstatic, §putstatic, §invokestatic).
    Todas estas instrucciones hacen referencia a una clase directa o indirectamente a través de una referencia de campo o una referencia de método.
    Al ejecutar una instrucción nueva, la clase o interfaz a la que se hace referencia se inicializa si no se ha inicializado.
    Tras la ejecución de una instrucción getstatic, putstatic o invokestatic, la clase o interfaz que declaró el campo o método resuelto se inicializa si no se ha inicializado ya.
  • La primera invocación de una instancia de java.lang.invoke.MethodHandle que fue el resultado de la resolución de un mango método por la máquina virtual Java (§5.4.3.5) y que tiene una especie de 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), o 8 (REF_newInvokeSpecial).
  • Invocación de ciertos métodos reflectantes en la biblioteca de clases (§2.12), por ejemplo, en la clase Class o en el paquete java.lang.reflect.
  • La inicialización de una de sus subclases.
  • Su designación como la clase inicial en la puesta en marcha de Java Virtual Machine (§5.2).

Antes de inicialización, una clase o interfaz deben estar vinculados, es decir, verifica, preparado, y opcionalmente resuelven.

Dado que la Máquina Virtual de Java es multiproceso, la inicialización de una clase o interfaz requiere una sincronización cuidadosa, ya que algunos otros hilos pueden estar 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 se pueda solicitar recursivamente como parte de la inicialización de esa clase o interfaz.

La implementación de la Máquina Virtual Java es responsable de cuidar la sincronización y la inicialización recursiva mediante el siguiente procedimiento.
Se supone que el objeto Class ya se ha verificado y preparado, y que el objeto contiene Class estado que indica una de las cuatro situaciones:

  • Este objeto Class se verifica y preparados, pero no se ha iniciado.
  • Este objeto Class está siendo inicializado por un hilo en particular.
  • Este objeto Class está completamente inicializado y listo para usar.
  • Este objeto Class está en un estado erróneo, quizás porque se intentó la inicialización y falló.
+0

+1 para su actualización. – sunleo

Cuestiones relacionadas