views:

303

answers:

2

Is there a way to write a generic loop to iterate over an arbitrary Enum? For example:

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

You can not do the above, because the Enum class does not have a method called values() like the implemented Enum classes. The above for loop works fine for a class that is defined as an enum.

+2  A: 

This is cheap, but should work (at least according to my testing):

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

This works because EnumSet has special magical access to non-public members of Enum, which allows it to enumerate the enum's values despite the lack of a values method.

Chris Jester-Young
It's not magic. Each enum type `T` has a *public* static method `T[] T.values()`. `EnumSet` uses reflection to access it but it doesn't need special privileges to do that.
finnw
@finnw: It does not use reflection! (See implementation of `EnumSet.getUniverse`.) It uses something very much like @axtavt's answer (`getEnumConstants`), but in a more magical way (`SharedSecrets.getJavaLangAccess().getEnumConstantsShared`).
Chris Jester-Young
Anyway, axtavt's answer is better than mine, so I encourage everyone to upvote that instead. :-P
Chris Jester-Young
+8  A: 

It works exactly the same way as if the Class is passed:

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);
axtavt
+1 Thanks, I learnt something new about how to access enumeration members!
Chris Jester-Young
I like this answer, although, I'd like to modify the method signature a bit, the signature should be:public static <E extends Enum<?>> void iterateOverEnumsByInstance(E e)andpublic static <E extends Enum<?>> void iterateOverEnumsByClass(Class<E> c)
Nick