2012-05-22 18 views
31

Estoy tratando de utilizar bloques estáticos como esto:Comportamiento de bloques estáticos con la herencia

tengo una clase base llamada Base.java

public class Base { 

    static public int myVar; 

} 

Y una clase derivada Derived.java:

public class Derived extends Base { 

    static 
    { 
     Base.myVar = 10; 
    } 
} 

Mi función main es así:

public static void main(String[] args) { 
    System.out.println(Derived.myVar); 
    System.out.println(Base.myVar); 
} 

Esto imprime la salida puesto como 0 0 donde como esperaba 10 0. ¿Alguien puede explicar este comportamiento? Además, si quiero que mis clases derivadas establezcan los valores para una variable estática, ¿cómo puedo lograr eso?

+0

Porque la clase no se inicializa, por lo que el bloque estático no se inicializa. pero descomenta (nuevo Derivado()) imprimirá 10,10, pero nunca imprimirá 10,0 – Guest

Respuesta

21

Según tengo entendido. No llama a ninguna propiedad Derived (myVar pertenece a Base, no a Derived). Y java no está ejecutando bloque estático desde Derived. Si agrega un campo estático al Derived y accede a él, entonces java ejecuta todos los bloques estáticos.

class Base { 

    static public int myVar; 

} 


class Derived extends Base { 

    static public int myVar2; 

    static 
    { 
     Base.myVar = 10; 
    } 
} 


public class Main { 
    public static void main(String[] args) throws Exception { 
     System.out.println(Derived.myVar2); 
     System.out.println(Base.myVar); 
    } 
} 

De la especificación de Java, cuando se inicializa la clase (y bloque estático consiguió ejecutado):

12,4.1 Cuando se produce la inicialización Una clase o interfaz tipo T se inicializará inmediatamente antes de la primera aparición de cualquiera de los siguientes:

• T es una clase y se crea una instancia de T.
• T es una clase y se invoca un método estático declarado por T.
• Se asigna un campo estático declarado por T.
• Se utiliza un campo estático declarado por T y el campo no es una variable constante (§4.12.4).
• T es una clase de nivel superior (§7.6) y se ejecuta una declaración de afirmación (§14.10) léxicamente anidada dentro de T (§8.1.3).

+0

[Eso no es verdad] (http://ideone.com/ieSfG) –

+3

@Jigar pero no accediste a 'j'. –

+0

ok le consiguió <---> –

1

Hay una sola copia de myVar y las clases principal y secundaria compartirán lo mismo. Hasta y a menos que se inicie la clase infantil.

6

Los bloques de inicializadores estáticos no se ejecutan hasta que se inicializa la clase. Ver Java Language Specification párrafos 8.7 (inicializadores estáticos) y 12.4.1 (Cuando se produce la inicialización):

Un inicializador estático declarado en una clase se ejecuta cuando la clase es inicializado (§12.4.2). Junto con cualquier inicializador de campo para las variables de clase (§8.3.2), los inicializadores estáticos se pueden usar para inicializar las variables de clase de la clase.

Aquí hay un ejemplo similar directamente de JLS 12.4.1:

class Super { 
    static int taxi = 1729; 
} 
class Sub extends Super { 
    static { System.out.print("Sub "); } 
} 
class Test { 
    public static void main(String[] args) { 
    System.out.println(Sub.taxi); 
    } 
} 

Este programa imprime solamente:

1729 

porque el Sub clase no se inicializa ; la referencia a Sub.taxi es una referencia a un campo realmente declarado en la clase Super y no activa la inicialización de la clase Sub .

+3

No es cierto. http://ideone.com/XaNhQ –

+1

@NikitaBeloglazov: en su ejemplo, el bloque estático funciona, porque la Base de clase de nivel superior se inicializa cuando se hace referencia a Derived. Consulte JLS "12.4.1 cuando ocurre la inicialización" para más detalles, el procedimiento de inicialización es bastante complicado: 'Una referencia a un campo estático (§8.3.1.1) causa la inicialización de la interfaz de clase o que realmente lo declara, aunque se puede hacer referencia a través del nombre de una subclase, una subinterfaz o una clase que implementa una interfaz. – esaj

+2

Sí, tiene razón. Pero su ejemplo puede ser confuso, porque parece que la clase se inicializó solo cuando se creó la instancia de la clase. –

0

Cuando hacemos

class Base { 

public static int myVar = 0; 
static { 
    System.out.println("Base"); 
} 

}

clase derivada se extiende Base {

static { 
    System.out.println("Derived"); 
    Base.myVar = 9; 

} 

}

public class {StaticBlock

public static void main(String[] args) { 

    System.out.println(Base.myVar); 
    System.out.println(Derived.myVar); 
} 

}

la salida será Base 0 0 Eso significa bloque estático de la clase derivada no ejecutar .. !!

+0

Compruebe la salida. Imprime: Base Derivada 9 – HakunaMatata

Cuestiones relacionadas