Java 如何遍历泛型枚举的值?

Java 如何遍历泛型枚举的值?,java,generics,enums,Java,Generics,Enums,使用此代码: enum MyEnum { A(1, 2), B(3, 4); private final int a; private final int b; MyEnum(int a, int b) { this.a = a; this.b = b; } } class GetValuesFromEnum<E extends Enum<E>> { public void pr

使用此代码:

enum MyEnum {
    A(1, 2),
    B(3, 4);

    private final int a;
    private final int b;

    MyEnum(int a, int b) {
        this.a = a;
        this.b = b;
    }
}

class GetValuesFromEnum<E extends Enum<E>> {
    public void printValues() {
        // This causes "cannnot find symbol" error during compilation
        for (E value : E.values()) {
            System.out.println(value);
        }

    }
}

public class Main {
    public static void main(String[] args) {
        new GetValuesFromEnum<MyEnum>().printValues();
    }
}
enum MyEnum{
A(1,2),
B(3,4);
私人终审法院;
私人最终int b;
髓鞘(内部a、内部b){
这个a=a;
这个.b=b;
}
}
类GetValuesFromEnum{
public void printValues(){
//这会导致编译期间出现“找不到符号”错误
对于(E值:E.values()){
系统输出打印项次(值);
}
}
}
公共班机{
公共静态void main(字符串[]args){
新的GetValuesFromEnum().printValues();
}
}

对泛型枚举调用
values()
,会导致编译时出错。是否可以以某种方式检索通用枚举的值?

您可以按以下方式修改代码:

class GetValuesFromEnum<E extends Enum<E>> {
    private Class<E> clazz;

    public GetValuesFromEnum(Class<E> clazz) {
        assert clazz.isEnum();
        this.clazz = clazz;
    }

    public void printValues() {
        for (E value : EnumSet.allOf(clazz)) {
            System.out.println(value);
        }

    }
}

public class Main {
    public static void main(String[] args) {
        new GetValuesFromEnum<>(MyEnum.class).printValues();
    }
}
class GetValuesFromEnum{
私人课堂;
public GetValuesFromEnum(类别分类){
断言clazz.isEnum();
this.clazz=clazz;
}
public void printValues(){
对于(E值:EnumSet.allOf(clazz)){
系统输出打印项次(值);
}
}
}
公共班机{
公共静态void main(字符串[]args){
新的GetValuesFromEnum(MyEnum.class).printValues();
}
}

为了能够在运行时访问枚举值,您应该知道运行时的类(例如,在字段中存储
class
对象)。由于擦除,泛型参数不足。还要注意EnumSet.allOf的用法:通常,获取所有枚举常量的方法非常便宜,因为它重用内部枚举常量数组而不是复制它。

您可以通过以下方式修改代码:

class GetValuesFromEnum<E extends Enum<E>> {
    private Class<E> clazz;

    public GetValuesFromEnum(Class<E> clazz) {
        assert clazz.isEnum();
        this.clazz = clazz;
    }

    public void printValues() {
        for (E value : EnumSet.allOf(clazz)) {
            System.out.println(value);
        }

    }
}

public class Main {
    public static void main(String[] args) {
        new GetValuesFromEnum<>(MyEnum.class).printValues();
    }
}
class GetValuesFromEnum{
私人课堂;
public GetValuesFromEnum(类别分类){
断言clazz.isEnum();
this.clazz=clazz;
}
public void printValues(){
对于(E值:EnumSet.allOf(clazz)){
系统输出打印项次(值);
}
}
}
公共班机{
公共静态void main(字符串[]args){
新的GetValuesFromEnum(MyEnum.class).printValues();
}
}

为了能够在运行时访问枚举值,您应该知道运行时的类(例如,在字段中存储
class
对象)。由于擦除,泛型参数不足。还要注意
EnumSet.allOf
的用法:获取所有枚举常量通常是一种非常便宜的方法,因为它重用内部枚举常量数组而不是复制它。

除了@Tagir Valeev的答案外,另一种在运行时检索枚举值的方法是通过
java.lang.Class.getEnumConstants()
方法

public void printValues(Class<? extends Enum<?>> enumCls) {
    for(Object obj: enumCls.getEnumConstants()) {
        System.out.println(obj);
    }   
}
public void打印值(类>enumCls){
对于(对象对象对象:enumCls.getEnumConstants()){
系统输出打印项次(obj);
}   
}

除了@Tagir Valeev的答案之外,在运行时检索枚举值的另一种方法是通过
java.lang.Class.getEnumConstants()
方法

public void printValues(Class<? extends Enum<?>> enumCls) {
    for(Object obj: enumCls.getEnumConstants()) {
        System.out.println(obj);
    }   
}
public void打印值(类>enumCls){
对于(对象对象对象:enumCls.getEnumConstants()){
系统输出打印项次(obj);
}   
}

是否可能以某种方式对用户隐藏获取枚举的
?@GillBates,不太可能。但我可能不明白你的意思。在您的代码中是
GetValuesFromEnum()
,在我的代码中是
GetValuesFromEnum(MyEnum.class)
。这是最大的区别吗?是的,这就是我要说的。@GillBates,请注意,即使是JDK EnumSet/EnumMap也必须明确知道enum类或至少一个enum值(因此可以通过
.getClass()
从中提取enum类)。例如,请参阅构造函数JavaDoc:“IllegalArgumentException-如果m不是EnumMap实例且不包含任何映射”。它无法从任意空映射构造。该类是必需的。是否可能以某种方式对用户隐藏enum的获取
。但我可能不明白你的意思。在您的代码中是
GetValuesFromEnum()
,在我的代码中是
GetValuesFromEnum(MyEnum.class)
。这是最大的区别吗?是的,这就是我要说的。@GillBates,请注意,即使是JDK EnumSet/EnumMap也必须明确知道enum类或至少一个enum值(因此可以通过
.getClass()
从中提取enum类)。例如,请参阅构造函数JavaDoc:“IllegalArgumentException-如果m不是EnumMap实例且不包含任何映射”。它无法从任意空映射构造。这门课是必要的。