2010-02-04 31 views
12

¿Hay alguna manera de escribir un ciclo genérico para iterar sobre un Enum arbitrario? Por ejemplo:¿Cómo escribo un bucle for genérico para un Java Enum?

public static void putItemsInListBox(Enum enum, ListBox listbox){ 
    for(Enum e : enum.values(){ 
     listBox.addItem(e.toString(), String.valueOf(e.ordinal()); 
    } 
} 

No se puede hacer lo anterior, porque la clase de enumeración no tiene un método llamado valores() como las clases de enumeración implementadas. El ciclo de arriba para funciona bien para una clase que se define como una enumeración.

+0

Como quieres un conjunto de enumeraciones no una enumeración, me gustaría sugerir que pasa en una 'Iterable' o somesuch. –

Respuesta

21

Funciona exactamente de la misma manera que si se aprueba la Class:

public static <E extends Enum<?>> void iterateOverEnumsByInstance(E e) 
{ 
    iterateOverEnumsByClass(e.getClass()); 
} 

public static <E extends Enum<?>> void iterateOverEnumsByClass(Class<E> c) 
{ 
    for (E o: c.getEnumConstants()) { 
     System.out.println(o + " " + o.ordinal()); 
    } 
} 

Uso:

enum ABC { A, B, C } 
... 
iterateOverEnumsByClass(ABC.class); 
iterateOverEnumsByInstance(ABC.A); 
+1

+1 Gracias, ¡aprendí algo nuevo sobre cómo acceder a los miembros de enumeración! –

+0

me gusta esta respuesta, aunque, me gustaría modificar la firma del método un poco, la firma debe ser: public static > iterateOverEnumsByInstance anular (E e) y public static > void iterateOverEnumsByClass (clase c) – Nick

2

Ésta es barato, pero debería funcionar (al menos según mis pruebas):

public static <T extends Enum<T>> void putItemsInListBox(Class<T> cls, ListBox listbox) { 
    for (T item : EnumSet.allOf(cls)) 
     listbox.addItem(item.toString(), String.valueOf(item.ordinal())); 
} 

Esto funciona porque EnumSet tiene acceso mágica especial para los miembros no públicos de Enum, lo que le permite enumerar los de enumeración valores a pesar de la falta de un método values.

+0

No es mágico. Cada tipo enum 'T' tiene un * static * método estático' T [] T.values ​​() '. 'EnumSet' utiliza la reflexión para acceder a ella, pero no necesita privilegios especiales para hacerlo. – finnw

+1

@finnw: ¡No usa el reflejo! (Consulte la implementación de 'EnumSet.getUniverse'.) Utiliza algo muy parecido a la respuesta de @ axtavt (' getEnumConstants'), pero de una manera más mágica ('SharedSecrets.getJavaLangAccess(). GetEnumConstantsShared'). –

+0

De todos modos, la respuesta de axtavt es mejor que la mía, así que animo a todos a que voten en lugar de eso. :-P –

Cuestiones relacionadas