2015-07-22 5 views
4

Я пытаюсь создать динамическую оболочку, которая использует отражение для доступа к свойствам объектов. Мой подход работает с разными объектами, но у меня все еще есть проблема с Enums.Как конфертировать из String в Enum динамически?

Предположим, у меня уже есть правильный сеттер и геттер, и я хочу вызвать их в разных ситуациях. Например, я пытаюсь сохранить заданное значение с помощью следующего кода:

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); 
    } 
} 

Как преобразовать объект типа String в нужное значение Enum?

Я знаю о MyEnum.valueOf(String) ... но что, если я не могу назвать Enum в моем исходном коде? Мне не удалось использовать что-то вроде

this.value = Enum.valueOf(this.getter.getReturnType(), this.value); 
+0

Ну, я думаю, вы можете использовать '.getDeclaredFields()' из объекта класса ... – fge

+0

Я знаю поле ... даже getter и setter. На данный момент я не могу преобразовать в соответствующий элемент Enum. –

+0

В чем проблема с высказыванием this.value = YourEnum.valueOf (theString)? – dsharew

ответ

3

Учитывая класс Enum и значение строки можно преобразовать в объект Enum, соответствующий строку с помощью следующего статического метода, определенного в java.lang.Enum:

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

например,

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

Обратите внимание, что Enum.valueOf бросает IllegalArgumentException, если нет соответствующей константы перечисления.

Вы не можете использовать Enum.valueOf без литья в своем методе, поскольку getter.getReturnType() - это Class<?>.

Так вспомогательная функция может обращаться к броску:

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

и вы просто использовать его в вашем коде:

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

Заметим, что любое решение, которое перебирает Enum.getEnumConstants() создаст временный массив для константы, тогда как Enum.valueOf использует внутренний кеш.

+0

Эта вспомогательная функция - хорошая точка ... синтаксис exakt блокировал мои попытки до сих пор. Спасибо ... Я попробую. –

+0

Спасибо ... работает как шарм :) –

0

Только что нашел один путь ... но кажется «грязным» ... лучше?

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; 
     } 
    } 
} 
+0

как это работает? getEnumConstants действителен только в том случае, если класс имеет тип ENUM. – dsharew

+0

Нет, это не ... http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getEnumConstants() –

+0

Метод просто возвращает пустой список, если он не является применимо. Но я могу назвать это в любом классе. Он компилирует ... –

Смежные вопросы