Estoy tratando de encontrar una manera de iterar a través de los valores de una enumeración mientras uso genéricos. No estoy seguro de cómo hacer esto o si es posible.
El siguiente código ilustra lo que quiero hacer. Tenga en cuenta que el código T.values () no es válido en el siguiente código.
public class Filter<T> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
this.selectedOption = selectedOption;
for (T option : T.values()) { // INVALID CODE
availableOptions.add(option);
}
}
}
Así es como crearía una instancia de un objeto Filter:
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);
La enumeración se define de la siguiente manera:
public enum TimePeriod {
ALL("All"),
FUTURE("Future"),
NEXT7DAYS("Next 7 Days"),
NEXT14DAYS("Next 14 Days"),
NEXT30DAYS("Next 30 Days"),
PAST("Past"),
LAST7DAYS("Last 7 Days"),
LAST14DAYS("Last 14 Days"),
LAST30DAYS("Last 30 Days");
private final String name;
private TimePeriod(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Me doy cuenta de que puede que no tenga sentido copiar los valores de una enumeración a una lista, pero estoy usando una biblioteca que necesita una lista de valores como entrada y no funcionará con enumeraciones.
EDITAR 5/2/2010:
La mayoría de las respuestas propuestas son muy similares y sugieren hacer algo como esto:
class Filter<T extends Enum<T>> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
Class<T> clazz = (Class<T>) selectedOption.getClass();
for (T option : clazz.getEnumConstants()) {
availableOptions.add(option);
}
}
}
Esto funcionaría muy bien si puedo estar seguro de que selectedOption tiene un valor no nulo. Desafortunadamente, en mi caso de uso, este valor a menudo es nulo, ya que también hay un constructor público Filter () sin argumentos. Esto significa que no puedo hacer un selectedOption.getClass () sin obtener un NPE. Esta clase de filtro gestiona una lista de opciones disponibles cuál de las opciones está seleccionada. Cuando no se selecciona nada, selectedOption es nulo.
Lo único que puedo pensar para resolver esto es pasar una clase en el constructor. Entonces algo como esto:
class Filter<T extends Enum<T>> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(Class<T> clazz) {
this(clazz,null);
}
public Filter(Class<T> clazz, T selectedOption) {
this.selectedOption = selectedOption;
for (T option : clazz.getEnumConstants()) {
availableOptions.add(option);
}
}
}
¿Alguna idea de cómo hacer esto sin necesidad de un parámetro Class adicional en los constructores?
getClass
código también fallará si la constante de enumeración es una subclase anónima ( ejemplo ).getDeclaringClass
debe usarse en su lugar.