我有一个匿名内部类的枚举,如:
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
。
这方面有好的工作吗?
答案 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
))可以为您提供所需的结果。