studio programacion móviles libros desarrollo desarrollar curso con aprende aplicaciones java jls

java - móviles - manual de programacion android pdf



Orden de inicialización de campos finales (2)

Aquí hay un código que llama al método estático Af () en la clase que aún no se ha inicializado. ¿Alguien puede explicar el comportamiento de este código en términos de JLS?

class A { final static Object b = new B(); final static int S1 = 1; final static Integer S2 = 2; static void f() { System.out.println(S1); System.out.println(S2); } } class B { static { A.f(); } } public class App { public static void main( String[] args ) { A.f(); } }

Salida:

1 null 1 2


Parece que este problema no pertenece a JLS , pero tenemos trato con JVMS .

En la etapa de Linking antes del proceso de resolution , hay un subestado de Preparation , que implica:

crear los campos estáticos para una clase o interfaz e inicializar dichos campos a sus valores predeterminados

y más:

Los inicializadores explícitos para campos estáticos se ejecutan como parte de la inicialización (§5.5), no de preparación

mientras que la initialization incluye:

La ejecución de cualquiera de las instrucciones de la Máquina Virtual Java nuevas.

La inicialización de tipos primitivos incluye escribir su valor inicial. Para los campos de tipo de referencia, su valor predeterminado es null porque antes de la subestadial de Resolution jvm no "sabe" qué clase está asociada a un nombre de referencia simbólico apropiado de una clase.


Af() en App.main() desencadena la inicialización de la clase A

Todas las variables constantes son inicializadas. La única variable constante es S1 , que ahora es 1 .

Luego, los otros campos estáticos se inicializan en orden textual. b es el primer campo, que activa la inicialización de la clase B , que a su vez llama a Af() . S2 es simplemente null porque aún no está inicializado. La inicialización de b está ahora completa. Por último, pero no menos importante, S2 se inicializa en el objeto Integer 2 .

S2 no es una variable constante porque no es del tipo primitivo int sino del tipo de referencia Integer . S2 = 2; es una abreviatura de boxeo automático para S2 = Integer.valueOf(2); .

Si un declarador en una declaración de campo tiene un inicializador de variable, entonces el declarador tiene la semántica de una asignación (§15.26) a la variable declarada.

[…]

Tenga en cuenta que static campos static que son variables constantes (§4.12.4) se inicializan antes que otros campos static (§12.4.2). Esto también se aplica en las interfaces (§9.3.1). Nunca se observará que tales campos tengan sus valores iniciales predeterminados (§4.12.5), incluso por programas tortuosos.

8.3.2. Inicialización de campo

Una variable constante es una variable final de tipo primitivo o tipo String que se inicializa con una expresión constante (§15.28). Si una variable es constante o no, puede tener implicaciones con respecto a la inicialización de clase (§12.4.1), compatibilidad binaria (§13.1, §13.4.9) y asignación definida (§16 (Asignación definida)).

4.12.4. Variables final

Una expresión constante es una expresión que denota un valor de tipo primitivo o una String que no se completa abruptamente y se compone utilizando solo lo siguiente:

  • Literales de tipo primitivo y literales de tipo String

[…]

15.28. Expresiones constantes

Para cada clase o interfaz C, hay un bloqueo de inicialización único LC . La asignación de C a LC se deja a discreción de la implementación de la Máquina Virtual de Java. El procedimiento para inicializar C es el siguiente:

[…]

  1. De lo contrario, registre el hecho de que el subproceso actual está realizando la inicialización del objeto Class para C y libere LC .

    Luego, inicialice los campos static de C, que son variables constantes (§4.12.4, §8.3.2, §9.3.1).

[…]

  1. A continuación, ejecute los inicializadores de variable de clase y los inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en orden textual, como si fueran un solo bloque.

12.4.2. Procedimiento de Inicialización Detallado

Cada variable en un programa debe tener un valor antes de que se use su valor:

  • Cada variable de clase, variable de instancia o componente de matriz se inicializa con un valor predeterminado cuando se crea (§15.9, §15.10.2):

    […]

    • Para todos los tipos de referencia (§4.3), el valor predeterminado es null .

4.12.5. Valores iniciales de variables