¿Por qué el constructor de enum no puede acceder a campos y métodos estáticos? Esto es perfectamente válido con una clase, pero no está permitido con una enumeración.
Lo que estoy tratando de hacer es almacenar mis instancias de enumeración en un mapa estático. Considere este código de ejemplo que permite la búsqueda por abreviatura:
public enum Day {
Sunday("Sun"), Monday("Mon"), Tuesday("Tue"), Wednesday("Wed"), Thursday("Thu"), Friday("Fri"), Saturday("Sat");
private final String abbreviation;
private static final Map<String, Day> ABBREV_MAP = new HashMap<String, Day>();
private Day(String abbreviation) {
this.abbreviation = abbreviation;
ABBREV_MAP.put(abbreviation, this); // Not valid
}
public String getAbbreviation() {
return abbreviation;
}
public static Day getByAbbreviation(String abbreviation) {
return ABBREV_MAP.get(abbreviation);
}
}
Esto no funcionará ya que enum no permite referencias estáticas en su constructor. Sin embargo, funciona solo busque si se implementa como una clase:
public static final Day SUNDAY = new Day("Sunday", "Sun");
private Day(String name, String abbreviation) {
this.name = name;
this.abbreviation = abbreviation;
ABBREV_MAP.put(abbreviation, this); // Valid
}
final
). ¡Supongo que será difícil de atrapar!EnumSet.allOf
lugar deEnum.values()
? Pregunto porquevalues
es una especie de método fantasma (no puedo ver la fuenteEnum.class
) y no sé cuándo se creóEnum.values()
es más rápido si planea iterar sobre ellos con un bucle for mejorado (ya que devuelve una matriz), pero principalmente se trata de estilo y caso de uso. Probablemente sea mejor usarloEnumSet.allOf()
si desea escribir código que existe en la documentación de Java en lugar de solo en las especificaciones, pero muchas personas parecen estar familiarizadas con él deEnum.values()
todos modos.Cita de JLS, sección "Declaraciones del cuerpo de enumeración" :
fuente
tal vez esto es lo que quieres
fuente
Collections.unmodifiableMap()
es una muy buena práctica aquí. +1El problema se resolvió mediante una clase anidada. Ventajas: es más corto y también mejor por el consumo de CPU. Contras: una clase más en la memoria JVM.
fuente
Cuando se carga una clase en la JVM, los campos estáticos se inicializan en el orden en que aparecen en el código. Por ejemplo
La salida será 0. Tenga en cuenta que la inicialización de test4 tiene lugar en el proceso de inicialización estático y durante este tiempo j aún no se ha inicializado como aparece más adelante. Ahora, si cambiamos el orden de los inicializadores estáticos de modo que j venga antes de test4. La salida será 6. Pero en el caso de Enums no podemos alterar el orden de los campos estáticos. Lo primero en enum deben ser las constantes que en realidad son instancias finales estáticas del tipo enum.Por lo tanto, para las enumeraciones siempre se garantiza que los campos estáticos no se inicializarán antes que las constantes enum.Ya que no podemos dar ningún valor sensible a los campos estáticos para su uso en el constructor de enum. , no tendría sentido acceder a ellos en el constructor enum.
fuente