[英]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.