繁体   English   中英

Java枚举匿名内部类和反射

[英]Java enum anonymous inner class and reflection

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

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而不是package.Status

有没有解决的办法?

您只需要更改查找所需方法的方法即可。 类似于以下内容的东西应该起作用:

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

将其与您现有的代码链接在一起(在返回的Method上调用.invoke (如果它不是null ))应该会为您提供所需的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM