Извлечение и установка значений enum с помощью отражения - PullRequest
3 голосов
/ 01 сентября 2011

Я пытаюсь установить для числа Enums значение по умолчанию. Я использую следующий метод:

private void checkEnum(Field field, String setMethod) {
    // TODO Auto-generated method stub
    try {
        String className = Character.toUpperCase(field.getName().charAt(0)) +
        field.getName().substring(1);
        Class<?> cls = Class.forName("com.citigroup.get.zcc.intf." + className);
        Object[] enumArray = cls.getEnumConstants();

        //set to the last Enum which is unknown
        invoke(setMethod, enumArray[enumArray.length - 1] );
    } catch(Exception e) {
        System.out.println(e.toString());
    }
}    

Проблема на самом деле в настройке Enum. Я извлек тип enum, но затем вызвал MethodInvoker. Передача объекта Enum является проблемой. Все перечисления имеют следующий элемент в качестве последнего элемента массива перечислений.

EnumName.UNKNOWN

Однако это не устанавливается с помощью метода invoke, который выглядит следующим образом:

private Object invoke(String methodName, Object newValue) {
    Object value = null;
    try {
        methodInvoker.setTargetMethod(methodName);

        if (newValue != null) {
            methodInvoker.setArguments(new Object[]{newValue});
        } else {
            methodInvoker.setArguments(new Object[]{});             
            }
        methodInvoker.prepare();
        value = methodInvoker.invoke();
    } catch (ClassNotFoundException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(),e);
    } catch (NoSuchMethodException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(),e);
    } catch (java.lang.reflect.InvocationTargetException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(),e);
    } catch (IllegalAccessException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(),e);
    }

    return value;
}

Так что я заблудился, почему

invoke(setMethod, enumArray[enumArray.length -1] );

Не устанавливает мой Enum

1 Ответ

3 голосов
/ 20 марта 2012

Я попытался запустить ваш код. Вызывал метод methodInvoker.prepare (): java.lang.IllegalArgumentException: требуется либо 'targetClass', либо 'targetObject'

Поэтому я добавил в класс отсутствующий параметр, и код работает, если я понимаю ваш вариант использования. Похоже, вы устанавливаете статическое поле, имя которого должно быть именем класса Enum в com.citigroup.get.zcc.intf с первым символом в имени поля в нижнем регистре.

Вот мой модифицированный код:

    public void checkEnum(Field field, String setMethod, Class clazz) {
      try {
        String className = Character.toUpperCase(field.getName().charAt(0)) +
            field.getName().substring(1);
        Class<?> cls = Class.forName("com.citigroup.get.zcc.intf." + className);
        Object[] enumArray = cls.getEnumConstants();

        //set to the last Enum which is unknown
        invoke(setMethod, enumArray[enumArray.length - 1], clazz);
      } catch (Exception e) {
        System.out.println(e.toString());
      }
    }
    private Object invoke(String methodName, Object newValue, Class clazz) {
      Object value = null;
      try {
        MethodInvoker methodInvoker = new MethodInvoker(); // this was missing
        methodInvoker.setTargetMethod(methodName);
        methodInvoker.setTargetClass(clazz);  // This was missing

        if (newValue != null) {
          methodInvoker.setArguments(new Object[]{newValue});
        } else {
          methodInvoker.setArguments(new Object[]{});
        }
        methodInvoker.prepare();
        value = methodInvoker.invoke();
      } catch (ClassNotFoundException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(), e);
      } catch (NoSuchMethodException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(), e);
      } catch (java.lang.reflect.InvocationTargetException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(), e);
      } catch (IllegalAccessException e) {
        throw new IllegalStateException("Method invocation failed. " + e.getMessage(), e);
      }

      return value;
    }
  }

Мой тестовый код был похож (Show - мой перечислимый класс, MethodNameHelper был ранее опубликован в StackExchange):

public class StackExchangeTestCase {
  protected static final Logger log = Logger.getLogger(StackExchangeTestCase.class);
  public static Show show;
  public static void setShow(Show newShow) {
    show = newShow;
  }

  @Test
  public void testJunk() throws Exception {

    Method me = (new Util.MethodNameHelper(){}).getMethod();
    Class<?> aClass = me.getDeclaringClass();
    Field att1 = aClass.getField("show");
    show = null;

    methodNameHelper.checkEnum(att1, "setShow", aClass);

    System.out.println(show); // worked
  }
}
...