Gill Bates
Gill Bates

Reputation: 15137

How to traverse values of a generic Enum?

With this code:

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

Calling values() on generic enum causes an error in compile time. Is it possible to somehow retrieve values of generic enum?

Upvotes: 1

Views: 139

Answers (2)

Sharon Ben Asher
Sharon Ben Asher

Reputation: 14328

in addition to @Tagir Valeev's answer, another way to retrieve enum values at runtime is through java.lang.Class.getEnumConstants() method

public void printValues(Class<? extends Enum<?>> enumCls) {
    for(Object obj: enumCls.getEnumConstants()) {
        System.out.println(obj);
    }   
}

Upvotes: 3

Tagir Valeev
Tagir Valeev

Reputation: 100199

You can modify your code in the following manner:

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

To be able to access enum values in runtime, you should know the class in runtime (for example, store the Class object in the field). Generic parameter is not enough due to erasure. Also note the usage of EnumSet.allOf: usually it's very cheap way of getting all the enum constants as it reuses internal enum constants array instead of copying it.

Upvotes: 2

Related Questions