method inner example create classes java inner-classes static-members

java - example - method-local inner class



Por qué los campos estáticos(no los definitivos) están restringidos en la clase interna en java (5)

Posible duplicado:
¿Por qué Java prohíbe los campos estáticos en las clases internas?

Estaba revisando la especificación y comprendí que no es posible tener el miembro estático en la clase interna que no es la constante de tiempo de compilación final.

class HasStatic { static int j = 100; } class myInnerClassTest { class Inner extends HasStatic { static final int x = 3; // OK: compile-time constant static int y = 4; // Compile-time error: an inner class } static class NestedButNotInner{ static int z = 5; // OK: not an inner class } interface NeverInner {} // Interfaces are never inner }

Mientras que obtuve del ¿Por qué podemos tener miembros finales estáticos pero no podemos tener un método estático en una clase interna? que puede heredar el miembro estático de su clase propietaria. Pero ¿por qué no debería? ¿Qué principal de OOP le duele?


Como saben, la clase interna puede heredar un miembro estático de su clase propietaria.

class HasStatic { static int j = 100; } class myInnerClassTest { class Inner extends HasStatic { } public static void main(String[] args){ System.out.println(Inner.j); } }

Y se imprime "100".


Debido a que la clase interna está íntimamente asociada a la clase de nivel superior, debe tener una instancia de la clase externa para crear una vía interna.

Outer o = new Outer(); Inner i = o.new Inner();

Por lo tanto, esto está asociado con una instancia y no con una clase.


Su clase myInnerClassTest no está declarada como estática. Entonces, ¿qué significaría eso exactamente para que tenga un campo estático?

Podría ser

  • ¿Lo mismo para todas las instancias, sea cual sea la instancia adjunta?
  • ¿Lo mismo para todas las instancias de esta clase interna que tiene la misma instancia adjunta?

A primera vista, la mayoría de los programadores probablemente pensarían que es el primer caso, mientras que la lógica de encapsulación de la clase interna (no estática) probablemente debería llevar a la segunda opción. Cualquiera de los casos (o ambos con modificadores diferentes) necesitaría una nueva definición de static que probablemente no se consideró necesaria. Y en cualquier caso, los programadores estarían confundidos sobre el significado exacto.

De la especificación :

Una clase interna es una clase anidada que no se declara explícita o implícitamente como estática.

Las clases internas incluyen clases de miembros locales (§14.3), anónimas (§15.9.5) y no estáticas (§8.5).

Las clases internas no pueden declarar inicializadores estáticos (§8.7) o interfaces miembro, o se produce un error en tiempo de compilación.

Las clases internas no pueden declarar miembros estáticos, a menos que sean variables constantes (§4.12.4), o se produzca un error en tiempo de compilación.


Todas las restricciones están documentadas en JLS # 8.1.3. Clases internas e instancias adjuntas

Debido a que las declaraciones estáticas están asociadas con la Clase, si la declara dentro de la clase interna, se asociará con la instancia en lugar de la clase.

Las clases internas no estáticas son miembros de Object. Y para los miembros, la inicialización solo ocurre cuando se crea una instancia de objeto. Si se permitieran variables estáticas, la inicialización habría ocurrido antes de la creación de la instancia.

Es por eso que hay clases internas separadas non-static y static .

Siempre se necesita una instancia de clase externa para acceder a la excepción interna de la clase interna. Outer.Inner única excepción static inner class es static inner class para la cual no hay restricciones aplicables a las clases internas no estáticas.

static class Inner { static final int x = 3; // OK: compile-time constant static int y = 4;// OK static class NestedButNotInner {// OK } interface NeverInner {// OK }; }

Sin embargo, las constantes están permitidas y está documentada en JLS.


Según JLS : -

8.1.3 Clases internas e instancias adjuntas

Una clase interna es una clase anidada que no se declara explícita o implícitamente como estática. Las clases internas no pueden declarar inicializadores estáticos (§8.7) o interfaces de miembros. Las clases internas no pueden declarar miembros estáticos, a menos que sean campos constantes en tiempo de compilación (§15.28).

Cualquier variable local, parámetro de método formal o parámetro de controlador de excepción usado pero no declarado en una clase interna debe ser declarado final. Cualquier variable local, utilizada pero no declarada en una clase interna debe asignarse definitivamente (§16) antes del cuerpo de la clase interna.

Aparte de estas dos cosas , las cuales me parecieron importantes. Hay muchas más que puedes obtener de ahí. Hay una gran explicación sobre inner classes , anonymous inner classes y nested classes .

EXPLICACIÓN ACTUALIZADA : -

Solo piensa en ello. El bloqueo estático se ejecuta durante la inicialización de la clase y no puede inicializar una clase interna no estática sin tener una instancia de la clase envolvente, esa es la razón.

Las clases internas están asociadas con la instance de la clase envolvente. Son como otros atributos de instancia de la clase envolvente. Ahora, no tiene sentido incrustar un campo static en un contexto non-static . Sin embargo, si declararlos como constantes de tiempo de compilación que se permitirían.

NOTA : - El static final Object = null no es una constante de tiempo de compilación . Por lo tanto, no puedes tenerlos dentro de tu clase interna

Por otro lado, si su clase interna hubiera sido static , eso es en realidad una clase anidada, entonces puede declarar su campo estático, ya que aún estarán asociados a la clase, por lo que puede acceder a ellos incluso antes de incluir la clase en instancias.

Espero que tenga sentido..

ACTUALIZACIÓN 2 : -

public class A { class B { static int x = 0; } }

En el código anterior, static variable x será común para cada instancia de la clase B .. Además, cada instancia de la class A tendrá su propia copia de la class B (ya que JVM tendrá que cargar la clase B cada vez que una instance of A es creado)..

Entonces, static variable x no podría haber sido compartida entre todas las instancias de la class A , a menos que sean constantes de tiempo de compilación ... (Para hacerlo más directo : - Puedes hacerlo - Bx si ves a B como clase externa ... Pero la clase B es en sí misma diferente para cada instancia de la clase A. Por lo tanto, Bx será diferente para cada instancia de la clase A .. Por lo tanto, la variable estática x no se comparte entre diferentes instancias de la clase A .. No tiene sentido para una variable estática.

Espero ahora, que tenga sentido ..