Java枚举匿名内部类和反射

时间:2017-09-01 23:42:01

标签: java reflection enums

我有一个匿名内部类的枚举,如:

wall

我有一个类似

的模型
public enum Status {

    PRELIMINARY() {
    @Override
    boolean process() {
        return true;
    }

    SUBMITTED() {
    @Override
    boolean process() {
        return false;
    }

    abstract boolean process();

}

我需要使用反射来设置public class Foo { private Status status; public void setStatus(Status status) { this.status = status; } } ,如:

Foo.status

private static <T> void setFieldValue(Foo instance, Class<?> klazz, Object value) { try { Class<?> aClass = value.getClass(); // Is Status$1 instead of Status Method method = klazz.getDeclaredMethod(getSetterName('setStatus'), aClass); method.invoke(instance, value); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { if (!klazz.equals(Object.class)) { setFieldValue(instance, klazz.getSuperclass(), fieldName, value); } } } 不包含内部类并且是一个简单的枚举时,这是有效的,但对于上述Status类,它将抛出Status。这是因为我的值类将是NoSuchMethodException而不是package.Status$1

这方面有好的工作吗?

1 个答案:

答案 0 :(得分:1)

您只需要更改找到所需方法的方法。以下内容应该有效:

private static @Nullable Method findMethod(Class<?> klass,
                                           final String methodName,
                                           final Object... args) {

    @Nullable Method candidate = null;

    classSearch:
    while (klass != null) {

        // Check all the class' methods for a matching one.
        methodSearch:
        for (final Method method : klass.getDeclaredMethods()) {
            if (!method.getName().equals(methodName)) continue;

            final Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length != args.length) continue;

            // Check all parameters can come from the given args.
            for (int i = 0; i < args.length; i++) {
                if (!parameterTypes[i].isInstance(args[i])) continue methodSearch;
            }

            candidate = method;
            break classSearch;
        }

        // No matching method, check super class.
        klass = klass.getSuperclass();
    }

    // May be 'null' if no match was found.
    // Throw an Exception if this isn't a valid outcome in your case.
    return candidate;
}

将此与现有代码相关联(在返回的.invoke上调用Method(如果它不是null))可以为您提供所需的结果。