2010-02-04 3 views
12

C'è un modo per scrivere un ciclo generico per iterare su un Enum arbitrario? Per esempio:Come si scrive un ciclo generico per un Java Enum?

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

Non si può fare quanto sopra, perché la classe Enum non ha un metodo chiamato valori(), come le classi Enum implementate. Il ciclo precedente per funziona bene per una classe che è definita come enum.

+0

Come si desidera un set di enumerazioni non un enum, io suggerirei di passaggio in un 'Iterable' or somesuch. –

risposta

21

Funziona esattamente allo stesso modo come se il Class è passato:

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

Usage:

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

+1 Grazie, ho imparato qualcosa di nuovo su come accedere ai membri dell'enumerazione! –

+0

Mi piace questa risposta, anche se, mi piacerebbe modificare la firma del metodo un po ', la firma dovrebbe essere: public static > invalidare iterateOverEnumsByInstance (E e) e public static > void iterateOverEnumsByClass (Classe c) – Nick

2

Questo è a buon mercato, ma dovrebbe funzionare (almeno secondo il mio test):

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

Questo funziona perché EnumSet ha accesso speciale magico per i membri non pubblici di Enum, che le permette di enumerare le enum di valori nonostante la mancanza di un metodo values.

+0

Non è magico. Ogni tipo di enum 'T' ha un metodo statico * public *' T [] T.values ​​() '. 'EnumSet' usa la reflection per accedervi ma non ha bisogno di privilegi speciali per farlo. – finnw

+1

@finnw: non usa la riflessione! (Vedi implementazione di 'EnumSet.getUniverse'.) Usa qualcosa di molto simile alla risposta di @ axtavt (' getEnumConstants'), ma in un modo più magico ('SharedSecrets.getJavaLangAccess(). GetEnumConstantsShared'). –

+0

In ogni caso, la risposta di axtavt è migliore della mia, quindi incoraggio tutti a sviare quella invece. :-P –