6

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);
5
  • Well, I guess you can use .getDeclaredFields() from the class object... Commented Jul 22, 2015 at 8:59
  • I know the field... even getter and setter. I don't manage to convert to the proper Enum element at the moment. Commented Jul 22, 2015 at 9:01
  • what is the problem with saying this.value = YourEnum.valueOf(theString)? Commented Jul 22, 2015 at 9:03
  • You can't reference an Enum with this as they are implicitly static. Commented Jul 22, 2015 at 9:03
  • @DegenSharew I don't know YourEnum... it may be any of MyEnum1, MyEnum2, ... Commented Jul 22, 2015 at 9:06

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This helper function is a good point... the exakt syntax blocked my attempts so far. Thanks... I'll give this a try.
0

Just found one way... but it seems "dirty"... any better?

if (this.value instanceof String && this.getter.getReturnType().isEnum()) {
    for (Object v : this.getter.getReturnType().getEnumConstants()) {
        if (v.toString().equals(this.value)) {
            this.value = v;
            break;
        }
    }
}

3 Comments

how does this work then? getEnumConstants is only valid if the class is of type ENUM.
The method simply returns an empty list if it is not applicable. But I can call it on any class. It compiles...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.