Cuando invoco la variable estática y
mediante el uso de Checks.y
( Checks
ser una subclase), el bloque estático no se ejecuta y el valor de y
no se actualiza.
class Par {
static int y = 4;
}
class Checks extends Par {
static {
y = 5;
}
}
public class Check {
public static void main(String args[]) {
System.out.println(Checks.y); // here printing 4
}
}
Como estática es compartida entre todas las subclases, se supone que el valor de ser actualizado.
¿Cuál podría ser la razón detrás de esto?
El campo y
no es declarado por clase Checks
.
La lectura de los campos estáticos no lo hace la inicialización del disparador de la clase referenciada ( Checks
), a menos que la clase es aquella en la que se declara el campo (ver JLS citan a continuación). En este ejemplo, incluso si y
se accede a través Checks
, que sólo se activará la inicialización Par
porque Par
es la clase de declarar y
.
En otras palabras, la clase Checks
es en un sentido no se utiliza en tiempo de ejecución.
Esta es quizás una ilustración de por qué es erróneo acceso static
miembros a través de las subclases, algo que provoca una advertencia de tiempo de compilación.
Hay una explicación simple de la especificación :
12.4.1. Cuando ocurra la inicialización
Un tipo de clase o interfaz T se inicializará inmediatamente antes de la primera aparición de uno cualquiera de los siguientes:
T es una clase y se crea una instancia de T.
Un método estático declarada por T se invoca.
Se asigna un campo estático declarada por T.
Un campo estático declarado por T se utiliza y el campo no es una variable constante (§4.12.4).
T es una clase de nivel superior (§7.6) y una sentencia assert (§14.10) anidado dentro de léxico T (§8.1.3) se ejecuta.
...
Una referencia a un campo estático (§8.3.1.1) provoca la inicialización de sólo la clase o interfaz que realmente declara que, a pesar de que podría ser referido a través del nombre de una subclase, una subinterfaz, o una clase que implementa una interfaz.
La última nota explica por qué su subclase no se está inicializando.