Rokas
Rokas

Reputation: 157

Write a single generics method to cover multiple methods for String to Enum value conversion

I created two Java enums,

public enum TypeEnum {
    TYPE_A, TYPE_B
}

and

public enum FormatEnum{
    FORMAT_X, FORMAT_Y
}

Next, I wrote two functions to convert an incoming String to an enum value:

private TypeEnum convertType(String test) {
    return TypeEnum.valueOf(test);
}
private FormatEnum convertFormat(String test) {
    return FormatEnum.valueOf(test);
}

Next, I wanted to unify these two conversion methods under a single method with generics. I tried this in two ways:

private <T extends Enum> Enum convertToEnumValue(T localEnum, String value) {
    return T.valueOf(localEnum.getClass(), value);
}

and

private static <T extends Enum> T convertToEnumValue(Class<T> enumType, String value) {
    return (T) T.valueOf(enumType, value);
}

I couldn't write a call to these methods that would compile.

Is there a way to correct them to make them work?

Upvotes: 1

Views: 74

Answers (3)

DuncG
DuncG

Reputation: 15116

There is no need to declare your own method, as JDK java.lang.Enum already declares one:

FormatEnum y =Enum.valueOf(FormatEnum.class, "FORMAT_Y");

TypeEnum a = Enum.valueOf(TypeEnum.class, "TYPE_A");

This works because Enum is the base class of all enum types and so when you call TypeEnum.valueOf(s); you are calling Enum.valueOf(s)

Upvotes: 1

deduper
deduper

Reputation: 1964

…Is there a way to correct them to make them work?…

I got your examples to work with these very small corrections…:

class DeduperAnswer {

    private <T extends Enum> T convertToEnumValue(T localEnum, String value) {
        return ( T ) T.valueOf(localEnum.getClass(), value);
    }

    private static <T extends Enum> T convertToEnumValue(Class<T> enumType, String value) {
        return ( T ) T.valueOf(enumType, value);
    }        

    static public void main(String ...args){

        DeduperAnswer da = new DeduperAnswer();

        TypeEnum typB = da.convertToEnumValue(TypeEnum.TYPE_B, "TYPE_B");

        FormatEnum fmtX = convertToEnumValue(FormatEnum.FORMAT_X.getClass(), "FORMAT_X");
    }
}

Of course, there's more than one way to skin a cat — as the saying goes. But seeing as your solution works for you, you're good to go.

Upvotes: 1

Mate Szilard
Mate Szilard

Reputation: 108

I suspect you are looking for the following method:

public static <E extends Enum<E>> E toMember(Class<E> clazz, String name) {
    //TODO input validations;
    for (E member : clazz.getEnumConstants()) {
        if (member.name().equals(name)) {
            return member;
        }
    }
    return null; //Or throw element not found exception
}

//More elegant form of the previous one
public static <E extends Enum<E>> E toMember(Class<E> clazz, String name, E defaultMember) {
    //TODO input validations;
    for (E member : clazz.getEnumConstants()) {
        if (member.name().equals(name)) {
            return member;
        }
    }
    return defaultMember;
}

Note the generic E extends Enum<E>

Upvotes: 0

Related Questions