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