如何为Java枚举编写通用的for循环?

15

有没有一种方法编写通用循环以迭代任意枚举类型?例如:

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

您无法这样做,因为Enum类没有像已实现的Enum类一样的values()方法。上述for循环适用于定义为enum的类。


由于你需要一组枚举而不是一个枚举,我建议传入一个 Iterable 或类似的对象。 - Tom Hawtin - tackline
2个回答

24

它的工作方式与传递 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());
    }
}

使用方法:

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

1
+1 谢谢,我学到了如何访问枚举成员的新知识! - C. K. Young
我喜欢这个答案,不过我想要稍微修改一下方法签名,签名应该是:public static <E extends Enum<?>> void iterateOverEnumsByInstance(E e)和public static <E extends Enum<?>> void iterateOverEnumsByClass(Class<E> c) - Nick

2
这个方案看起来很便宜,但应该是可行的(至少根据我的测试结果):
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()));
}

这起作用的原因是 EnumSet 对于 Enum 的非公共成员有特殊的神奇访问权限,使其能够枚举枚举类型的值,尽管缺少 values 方法。


这不是魔术。每个枚举类型 T 都有一个 公共的 静态方法 T[] T.values()EnumSet 使用反射来访问它,但它不需要特殊的权限来实现。 - finnw
1
@finnw:它不使用反射!(请参见EnumSet.getUniverse的实现。)它使用类似于@axtavt答案的东西(getEnumConstants),但以更神奇的方式(SharedSecrets.getJavaLangAccess().getEnumConstantsShared)。 - C. K. Young
无论如何,axtavt的回答比我的更好,所以我鼓励大家支持他。:-P - C. K. Young

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接