Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert from String to Enum dynamically?

Tags:

java

enums

I'm trying to build a dynamic wrapper that uses reflection to access properties of objects. My approach works with different kinds of objects – but I still have an issue with Enums.

Let's assume I already have the proper setter und getter and I want to invoke them in different situations. For example I'm trying to save a given value via the following code:

public void save() {
    try {
        // Enums come in as Strings... we need to convert them!
        if (this.value instanceof String && this.getter.getReturnType().isEnum()) {

            // FIXME: HOW?

        }
        this.setter.invoke(this.entity, this.value);
    }
    catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        throw new RuntimeException("Die Eigenschaft " + this.property + " von Entity " + this.entity.getClass().getSimpleName() + " konnte nicht geschrieben werden!", ex);
    }
}

How can I convert the String object to the proper Enum value?

I know about MyEnum.valueOf(String)... but what if I can't name the Enum in my source code? I've not managed to use something like

this.value = Enum.valueOf(this.getter.getReturnType(), this.value);
like image 746
Daniel Bleisteiner Avatar asked Sep 28 '22 06:09

Daniel Bleisteiner


1 Answers

Given a Enum class and a string value you can convert to the Enum object corresponding to the string via the following static method defined in java.lang.Enum:

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

e.g.

java.awt.Window.Type type = Enum.valueOf(java.awt.Window.Type.class, "NORMAL");

Note that Enum.valueOfthrows an IllegalArgumentException if there is no corresponding enum constant.

You can't invoke Enum.valueOf without a cast from your method, since getter.getReturnType() is a Class<?>.

So a helper function might handle the cast:

@SuppressWarnings("unchecked")
private static <E extends Enum<E>> E getEnumValue(Class<?> c, String value)
{
     return Enum.valueOf((Class<E>)c, value);
}

and you just use it in your code:

if (this.value instanceof String && this.getter.getReturnType().isEnum())
     this.value = getEnumValue(getter.getReturnType(), (String)this.value));

Note that any solution which loops over Enum.getEnumConstants() will create a temporary array for the constants, whereas Enum.valueOf uses an internal cache.

like image 98
wero Avatar answered Oct 06 '22 20:10

wero