java - semana - ¿Por qué no se pueden declarar las enumeraciones localmente en un método?
nomenclatura enum java (5)
Hoy, me encontré codificando algo como esto ...
public class LocalEnums {
public LocalEnums() {
}
public void foo() {
enum LocalEnum {
A,B,C
};
// ....
// class LocalClass { }
}
}
y me sorprendí un poco cuando el compilador informó un error en la enum
local:
El miembro enum LocalEnum no puede ser local
¿Por qué no se pueden declarar las clases locales como enums ?
Encontré esto muy útil en ciertas situaciones. En el caso en el que estaba trabajando, el resto del código no necesitaba saber nada sobre la enum
.
¿Hay algún conflicto estructural / de diseño que explique por qué esto no es posible o podría ser una característica futura de Java?
"Los tipos de enumeración anidados son implícitamente estáticos". 8.9 Enums
Es razonable inferir que los tipos de enumeración anidados contienen implícitamente el modificador de acceso estático.
- "Es un error en tiempo de compilación si una declaración de clase local contiene uno de los siguientes modificadores de acceso: público, protegido, privado o estático". 14.3 14.3 Declaraciones locales de clase
Es extraño porque la definición de la clase interna de Java dice que las constantes de tiempo de compilación se pueden declarar estáticas, y un miembro de un Enum es claramente una constante de tiempo de compilación, además de que enum es una clase estática, supuestamente ...
8.1.3 Clases internas e instancias adjuntas
(...) Las clases internas no pueden declarar miembros estáticos, a menos que sean campos constantes de tiempo de compilación.
class Outer{
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
}
Rara vez me encuentro escribiendo algún tipo dentro de un método, a menos que sea una clase interna anónima. Sin embargo, puede escribir enumeraciones anidadas:
public class NestedEnum
{
private enum MyEnum
{
X, Y, Z
}
public void foo()
{
}
}
No creo que realmente quiera leer un método que declare un nuevo tipo dentro de él. ¿Tiene alguna razón concreta para querer declararlo dentro del método en lugar de solo como un tipo anidado? Puedo ver el argumento de que "ningún otro método necesita saber", pero creo que un comentario puede solucionarlo y dejar un código más legible.
http://mindprod.com/jgloss/enum.html ofrece una buena descripción de las enumeraciones de java: como se mencionó anteriormente, las enumeraciones se definen como estáticas, por lo que no pueden declararse como locales
Las enumeraciones son clases anidadas estáticas porque definen variables de miembro estáticas (los valores de enumeración) , y esto no está permitido para las clases internas : http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3
Actualización: estaba buscando en JLS
( especificación del lenguaje Java ) para obtener más detalles sobre las restricciones de las clases anidadas estáticas, y no lo encontré (aunque probablemente esté allí, oculto bajo un tema diferente). Desde una perspectiva de implementación pura, no hay razón para que esto no se pueda hacer. Así que sospecho que se trataba de un problema de filosofía del lenguaje: no debería hacerse, por lo tanto, no será compatible. Pero no estuve allí, así que eso es pura especulación.
Como comentario: si sus métodos son lo suficientemente grandes como para que necesiten sus propias enumeraciones, entonces es una señal firme de que necesita refactorización.