Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert String to enum value when enum type reference is a Class<?>?

I have code which is setting values on an object using its setter methods. One of the setters takes an Enum type as the method parameter. The code looks something like this:

    String value = "EnumValue1";
    Method setter = getBeanWriteMethod("setMyEnumValue");
    Class<?> type = setter.getParameterTypes()[0];
    Object convertedValue = null;
    if (type.isEnum()) {
       convertedValue = convertToEnum(value, type);
    } else {
       convertedValue = ClassUtils.convertType(value, type);
    }
    return convertedValue;

The question is what to put in the convertToEnum method. I know I could "brute force it" by iterating the enum constants (or the fields) of the type object, matching the value. Am I overlooking a simpler way to do it using Reflection? (I looked at several examples, but didn't find any where the enum was only know via Class).

like image 694
Sam Goldberg Avatar asked Jun 11 '13 18:06

Sam Goldberg


1 Answers

Off the top of my head:

  Enum<?> convertedValue = Enum.valueOf((Class<Enum>)type,  value);

This will convert a string to an enum constant of the Enum class of type

Edit: Now that I have a computer handy, I can see what actually works. Either of the below cases ran correctly without compiler warnings:

Enum<?> convertedValueA = Enum.valueOf(type, value);
Enum<?> convertedValueB = Enum.valueOf(type.asSubclass(Enum.class), value);

The second one calls asSubClass() which would do a runtime check to ensure that type is some enum class, but the valueOf() method has to make that check anyway in order to work correctly.

The following gave me a compile error:

Enum<?> convertedValueC = Enum.valueOf((Class<? extends Enum <?>>)type, value);

java: Foo.java:22: <T>valueOf(java.lang.Class<T>,java.lang.String) in java.lang.Enum cannot be applied to (java.lang.Class<capture#134 of ? extends java.lang.Enum<?>>,java.lang.String)

The intricacies of casting to wildcard types confuses me so I've probably tried the wrong cast. Plus the fact that it has no runtime effect means that it's easy to get it wrong and never find out.

like image 155
Adrian Pronk Avatar answered Oct 06 '22 00:10

Adrian Pronk