簡體   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