2010-02-04 7 views
12

Existe-t-il un moyen d'écrire une boucle générique pour itérer sur un Enum arbitraire? Par exemple:Comment écrire une boucle générique pour un Java Enum?

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

Vous ne pouvez pas faire ce qui précède, parce que la classe Enum ne dispose pas d'une méthode appelée valeurs() comme les classes Enum mises en œuvre. La boucle ci-dessus fonctionne correctement pour une classe définie comme une énumération.

+0

Comme vous voulez un ensemble de énumérations pas ENUM, je vous suggère de passer dans un "Iterable" ou somesuch. –

Répondre

21

Il fonctionne exactement de la même manière que si le Class est passé:

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()); 
    } 
} 

Utilisation:

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

+1 Merci, j'ai appris quelque chose de nouveau sur la façon d'accéder aux membres de l'énumération! –

+0

J'aime cette réponse, bien que, je voudrais modifier la signature de la méthode un peu, la signature doit être: public static > annuler iterateOverEnumsByInstance (E e) et public static > void iterateOverEnumsByClass (Classe c) – Nick

2

Ce ne coûte pas cher, mais devrait fonctionner (au moins selon mes tests):

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())); 
} 

Cela fonctionne parce que EnumSet a un accès spécial magique aux membres non publics de Enum, ce qui lui permet d'énumérer les années ENUM valeurs en dépit de l'absence d'une méthode values.

+0

Ce n'est pas magique. Chaque type enum 'T' a une méthode statique * public *' T [] T.values ​​() '. 'EnumSet' utilise la réflexion pour y accéder mais n'a pas besoin de privilèges spéciaux pour le faire. – finnw

+1

@finnw: Il n'utilise pas de réflexion! (Voir l'implémentation de 'EnumSet.getUniverse'.) Il utilise quelque chose qui ressemble beaucoup à la réponse de @ axtavt (' getEnumConstants'), mais de façon plus magique ('SharedSecrets.getJavaLangAccess(). GetEnumConstantsShared'). –

+0

Quoi qu'il en soit, la réponse d'axtavt est meilleure que la mienne, alors j'invite tout le monde à le changer. :-P –

Questions connexes