使用反射来获取方法;找不到接口类型的方法参数
当参数类型为接口时,如何根据参数值使用反射获取方法?
在以下情况下(基于此示例),newValue
将是一个名为 foo
的 List
。所以我会调用 addModelProperty("Bar", foo);
但这仅适用于我不使用接口而仅使用 LinkedList
.如何使用 newValue
的接口并从具有接口作为参数 addBar(List
的 model
获取方法?
public class AbstractController {
private final AbstractModel model;
public setModel(AbstractModel model) {
this.model = model;
}
protected void addModelProperty(String propertyName, Object newValue) {
try {
Method method = getMethod(model.getClass(), "add" + propertyName, newValue);
method.invoke(model, newValue);
} catch (NoSuchMethodException e) {
} catch (InvocationTargetException e) {
} catch (Exception e) {}
}
private Method getMethod(Class clazz, String name, Object parameter) {
return clazz.getMethod(name, parameter.getClass());
}
}
public class AbstractModel {
protected PropertyChangeSupport propertyChangeSupport;
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}
public class Model extends AbstractModel {
public void addList(List<String> list) {
this.list.addAll(list);
}
}
public class Controller extends AbstractController {
public void addList(List<String> list) {
addModelProperty(list);
}
}
public void example() {
Model model = new Model();
Controller controller = new Controller();
List<String> list = new LinkedList<String>();
list.add("example");
// addList in the model is only found if LinkedList is used everywhere instead of List
controller.addList(list);
}
How do I get a method using reflection based on a parameter value when the parameter type is an interface?
In the following case (based on this example), newValue
would be a List<String>
called foo
. So I would call addModelProperty("Bar", foo);
But this only works for me if I don't use the interface and only use LinkedList<String> foo
. How do I use an interface for newValue
and get the method from model
that has an interface as the parameter addBar(List<String> a0)
?
public class AbstractController {
private final AbstractModel model;
public setModel(AbstractModel model) {
this.model = model;
}
protected void addModelProperty(String propertyName, Object newValue) {
try {
Method method = getMethod(model.getClass(), "add" + propertyName, newValue);
method.invoke(model, newValue);
} catch (NoSuchMethodException e) {
} catch (InvocationTargetException e) {
} catch (Exception e) {}
}
private Method getMethod(Class clazz, String name, Object parameter) {
return clazz.getMethod(name, parameter.getClass());
}
}
public class AbstractModel {
protected PropertyChangeSupport propertyChangeSupport;
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}
public class Model extends AbstractModel {
public void addList(List<String> list) {
this.list.addAll(list);
}
}
public class Controller extends AbstractController {
public void addList(List<String> list) {
addModelProperty(list);
}
}
public void example() {
Model model = new Model();
Controller controller = new Controller();
List<String> list = new LinkedList<String>();
list.add("example");
// addList in the model is only found if LinkedList is used everywhere instead of List
controller.addList(list);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上,您必须搜索模型中的所有方法,并找到与您所拥有的参数兼容的方法。这有点混乱,因为一般来说,可能不止一个。
如果您只对公共方法感兴趣,那么
getMethods()
方法是最容易使用的,因为它为您提供了所有可访问的方法,而无需遍历类层次结构。You'll actually have to search through all the methods in your model and find those that are compatible with the arguments you have. It is a bit messy, because, in general, there might be more that one.
If you are interested in just public methods, the
getMethods()
method is the easiest to use, because it gives you all accessible methods without walking the class hierarchy.如果您不介意添加对 Apache Commons 的依赖项,您可以使用
MethodUtils.getMatchingAccessibleMethod(Class clazz, String methodName, Class[]parameterTypes)
。如果您介意添加此依赖项,您至少会发现查看 此方法是如何实现的。
If you don't mind adding a dependency to Apache Commons, you may use
MethodUtils.getMatchingAccessibleMethod(Class clazz, String methodName, Class[] parameterTypes)
.If you mind adding this dependency, you may at least find it useful to take a look at how this method is implemented.
另一个答案建议使用 Apache Commons 使用
MethodUtils.getMatchingAccessibleMethod< 获取
Method
对象/代码>。但是,看起来您除了立即在实例上调用
Method
对象之外,并未将其用于任何其他用途。在这种情况下,您可以改用 Apache Commons Lang 的MethodUtils.invokeMethod(Object object, String methodName, Object... args)< /代码>
。这不是仅仅返回
Method
对象,而是调用给定对象上的方法。Another answer suggested using Apache Commons to get the
Method
object usingMethodUtils.getMatchingAccessibleMethod
.However, it looks like you're not using the
Method
object for anything other than immediately invoking it on an instance. This being the case, you can instead use Apache Commons Lang'sMethodUtils.invokeMethod(Object object, String methodName, Object... args)
. Rather than just returning theMethod
object, this instead invokes the method on the given object.