class OuterClass1 { static private int a = 10; void get() { System.out.println("Outer Clas Method"); } static class StaticInnerClass { void get() { System.out.println("Inner Class Method:" + a); } } public static void main(String args[]) { OuterClass1.StaticInnerClass b = new OuterClass1.StaticInnerClass(); b.get(); System.out.println(ba); System.out.println(bc); } }Sé que la clase anidada estática puede acceder a los miembros de datos de la clase externa, entonces, ¿por qué no puedo acceder a la variable de la clase externa a través de la referencia de la clase interna, pero puedo acceder a ella usándola directamente en la clase interna como se indicó anteriormente?
La especificación del lenguaje Java proporciona las siguientes reglas para acceder a campos estáticos:
◆ Si el campo es estático:
- Se evalúa la expresión principal y se descarta el resultado. [...]
- Si el campo es un final que no está en blanco, el resultado es el valor de la variable de clase especificada en la clase o interfaz que es el tipo de la expresión principal.
Tenga en cuenta que la especificación no permite buscar campos estáticos en otras clases; sólo se considera el tipo inmediato de la expresión primaria.
En su caso, la expresión principal es simplemente b . Se evalúa, y su resultado se descarta sin efecto observable.
El tipo de la expresión principal b es OuterClass1.StaticInnerClass . Por lo tanto, Java trata a ba como OuterClass1.StaticInnerClass.a . Dado que la clase OuterClass1.StaticInnerClass no contiene un campo estático a , el compilador produce un error.
Cuando accede a campos dentro de un método de la clase, se aplica un conjunto diferente de reglas. Cuando el compilador ve a entrada
System.out.println("Inner Class Method:" + a); busca en la clase misma y continúa hacia las clases externas cuando el campo no está allí. Ahí es donde el compilador encuentra a , por lo que la expresión se compila correctamente.
Nota: Acceder a miembros estáticos a través de expresiones no estáticas es una mala idea. Consulte estas preguntas y respuestas para obtener una explicación .
No nos ha mostrado una clase interna, StaticInnerClass no es una clase interna. No existe tal cosa en Java como una "clase interna estática" porque una clase interna por definición es una clase anidada que no es estática. Solo las clases internas tienen acceso directo a los miembros de los tipos contenedores. Debido a que StaticInnerClass no es una clase interna, no tiene dicho acceso.