通过反射提取和设置枚举值

发布于 2024-12-02 05:18:31 字数 1914 浏览 3 评论 0原文

我正在尝试将一些枚举设置为默认值我使用以下方法:

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

问题实际上是设置枚举。我已经提取了枚举类型,但随后调用 MethodInvoker。事实证明,传入 Enum 对象是一个问题。所有枚举都将以下内容作为枚举数组的最后一个元素。

EnumName.UNKNOWN

然而,这不是通过调用方法设置的,如下所示:

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

Is not set my Enum

I am trying to set a number of Enums to default value I am using the following method:

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

The problem is actually setting the Enum. I have extracted the enum type but to then call the MethodInvoker. Passing in the Enum object is proving a problem. All the enums have the following as the last element of the enum array.

EnumName.UNKNOWN

However this is not being set via the invoke method which looks like:

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

So I'm lost as to why the

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

Is not setting my Enum

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你在我安 2024-12-09 05:18:31

我试图让你的代码运行。 methodInvoker.prepare() 调用抛出:
java.lang.IllegalArgumentException:需要“targetClass”或“targetObject”

因此,如果我理解您的用例,我在类中添加了缺少的参数,并且代码可以正常工作。
您似乎正在设置一个静态字段,其名称必须是 com.citigroup.get.zcc.intf 下的 Enum 类的名称,并且字段名称中的第一个字符小写。

这是我修改后的代码:

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

I attempted to get your code running. The methodInvoker.prepare() call was throwing:
java.lang.IllegalArgumentException: Either 'targetClass' or 'targetObject' is required

So I added in the class missing parameter and the code works, if I understand your use case.
You appear to be setting a static field whose name must be the name of an Enum class under com.citigroup.get.zcc.intf with the first character in the field name downcased.

Here is my modified code:

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

My test code resembled (Show is an enum class of mine, MethodNameHelper has been previously posted to 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
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文