2012-03-12 7 views
10

Tengo problemas para entender el orden en que ocurre la inicialización. este es el orden Asumí:¿En qué orden se ejecutan el bloque de inicializador y las definiciones de variables, etc.? (en java)

*Once per 
    1. Static variable declaration 
    2. Static block 
*Once per object 
    3. variable declaration 
    4. initialization block 
    5. constructor 

pero de acuerdo con este código Obviamente estoy equivocado:

class SomethingWrongWithMe 
    { 
     { 
      b=0;   //no. no error here. 
      int a = b; //Error: Cannot reference a field before it is defined. 
     } 
     int b = 0; 
    } 

Y el error desaparecería si hago esto:

class SomethingWrongWithMe 
    { 
     int b = 0; 
     { 
      b=0; 
      int a = b; //The error is gone. 
     } 
    } 

que pueda 't averiguar por qué no hay un error en

b=0; 
+0

¿Qué compilador estás usando? Oracles javac? O algunos IDE (al menos Eclipse trae su propio compilador) –

+0

Eclipse y Oracles javac se comporta de la misma manera en este escenario. – aioobe

+1

usando eclipse .. – Untitled

Respuesta

4

La especificación del lenguaje Java (sección 8.3.2.3) dice que se puede utilizar una variable de la izquierda lado de la mano de una expresión, es decir, asignarle, antes de que se declare, pero no puede usarlo en el lado derecho.

Todas las variables se inicializan a sus valores predeterminados, luego los inicializadores explícitos y los bloques anónimos se ejecutan en el orden en que se encuentran en el archivo de origen. Finalmente se llama al constructor.

Las estadísticas solo se ejecutan una vez en el primer uso de una clase.

El error de compilación parece ser una regla de Java en lugar de algo que necesariamente tiene sentido en todos los casos.

+0

pregunta de seguimiento: ok. Ahora entiendo la situación aquí. simplemente no puedo entender por qué hay tal característica. No me puedo imaginar un uso para eso.¿Por qué alguien querría asignar una variable en el bloque de inicialización antes de su declaración? ¿por qué no declararlo primero? – Untitled

+1

Acepto, y ¿por qué podemos asignarle un valor, pero no leer de él? El JLS dice que todas las variables se crean y se inicializan a los valores predeterminados antes de ejecutar cualquier código explícito, por lo que la variable existe y tiene un valor, simplemente no podemos leer de ella. Eso me parece extraño. –

+0

Se hace para evitar referencias circulares. P.ej. int a = b + 1; int b = a + 2; – ekaerovets

1

En primer lugar, sus suposiciones son más o menos correctas, excepto por el hecho de que las declaraciones (con inicialización, como int b = 0) y los bloques de inicializador de instancia se ejecutan en el orden en que se escriben.

int b = 0; // executed first 

{ 
    b = 1; // executed second 
} 

int a = b; // executed third 

También tenga en cuenta que la declaración es decir int b no se ejecuta . La declaración solo declara la existencia de la variable.

En cuanto al error que recibió (o, más bien, el error que no obtener) Estoy de acuerdo en que se ve extraño. Supongo que el compilador se ocupa de hacer referencia a una variable en una expresión y asignarle un valor de diferentes maneras. Al escribir en una variable en un inicializador de instancia, solo comprueba que la variable está allí, mientras que cuando lee de ella, requiere que se declare encima del bloque de inicializador de instancia. Veré si puedo encontrar una referencia para eso en el JLS.

3

Las definiciones de las variables no se hacen bloques "antes". Ambos se llevan a cabo al mismo tiempo, en el orden en que se definen

class SomethingWrongWithMe { 
    { 
     b = debug("block 1"); 
    } 
    int b = debug("define"); 
    { 
     b = debug("block 2"); 
    } 
    private int debug(String str) { 
     System.out.println(str); 
     return 0; 
    } 
} 

salida

block 1 
define 
block 2 
+1

Correcto, pero la pregunta de por qué puede escribir en una variable declarada debajo de la línea pero no leída de la misma variable no es respondida. – aioobe

Cuestiones relacionadas