简体   繁体   中英

How to create generic enum converter?

I want to write a generic class that can be used like new EnumConverter(MyEnum.class);

But hwo to I have to write that class so that it works with generic calls to enum.values() ?

public class EnumConverter {
    public EnumConverter(Class<Enum<?>> type) {
        this.type = type;
    }

    public EnumConverter convert(String text) {
        //error: Type mismatch: cannot convert from element type capture#1-of ? to Enum<?>
        for (Enum<?> candidate : type.getDeclaringClass().getEnumConstants()) {
            if (candidate.name().equalsIgnoreCase(text)) {
                return candidate;
            }
        }
    }
}

your question is inconsistent and not valid code: 1) this.type is not defined as a field 2) you define convert to return EnumConverter but return an Enum

to return a enum value of an enum from text you do not need generic stuff. you simply use:

Enum.valueOf(MyEnum.class, "TWO")

Your return type of method convert is wrong: Shoud be Enum instead of EnumConverter . And then you don't have to call getDeclaringClass() but use the Class you already have in type.

I would suggest an even more generic approach:

public static class EnumConverter<T extends Enum<T>>
{

    Class<T> type;

    public EnumConverter(Class<T> type)
    {
        this.type = type;
    }

    public Enum<T> convert(String text)
    {
        for (Enum<T> candidate : type.getEnumConstants()) {
            if (candidate.name().equalsIgnoreCase(text)) {
                return candidate;
            }
        }

        return null;
    }
}

Following is not a class like requested, but still an improvement over some other answers because it produces no warnings (java 11/IDEA 2020)

    static <Dest extends Enum<Dest>> Dest
    convertEnumStrict(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
        if (sourceEnum == null) {
            return null;
        }
        return Dest.valueOf(destinationClassType, sourceEnum.name());
    }

    static <Dest extends Enum<Dest>> Dest
    convertEnumOrNull(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
        try {
            return convertEnumStrict(destinationClassType, sourceEnum);
        } catch (IllegalArgumentException e) {
            return null;
        }
    }

Putting together the two best answers, you get a clean one liner:

public <T extends Enum<T>> T getEnumValue(Class<T> type, String str) {
    return Enum.valueOf(type, str);
}

In case if some looking for alternative solution with out for loop.

   // classType is target Enum
     public static Enum<?> toEnum(final Class<? extends Enum> classType, final Enum<?> enumObj) {
            if (enumObj == null) {
                return null;
            } else {
                return enumObj.valueOf(classType, enumObj + "");
            }

Usage:

 TestEnum1 enum1 = (TestEnum1) toEnum(TestEnum1.class, TestEnum1.HELLO_ENUM);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM