我有一个关于method.invoke()的问题。我正在使用以下代码构建方法:
public void exec(String property_name, Object value){
try{
Method method = some_class.getClass().
getMethod("set"+property_name, new Class[] {
value.getClass()
}
);
method.invoke(some_class, value);
}catch(Exception e){
e.printStackTrace();
}
}
我的some_class有方法:
public void setA(Test test){
// do something
}
setA函数的参数是接口,如下所示:
public interface Test{
public void write(String str);
}
当我使用第一个示例代码中的exec()函数和TestImpl(它是Test的实现)时,会引发异常,通知在some_class中找不到该方法。但是当我使用函数exec()与原始类而不是扩展或实现时,方法exec()工作正常。
我应该怎样做才能使用类的实现方法?
使用SSCCE进行更新,以防某些人需要:
public class test {
public static void main(String[] args) {
exec("Name", new TestClassImpl());
}
public static void exec(String property_name, Object value){
try{
some_class sc = new some_class();
Method method = sc.getClass().
getMethod("set"+property_name, new Class[] {
value.getClass()
}
);
method.invoke(sc, value);
}catch(Exception e){
e.printStackTrace();
}
}
}
class some_class{
public some_class(){}
public void setName(TestClass test){
System.out.println(test.name());
}
}
interface TestClass{
public String name();
}
class TestClassImpl implements TestClass{
public String name() {
return "sscce";
}
}
提前致谢, 谢尔盖。
答案 0 :(得分:2)
问题是new Class[] { value.getClass() }
。通过此操作,您可以搜索与参数类型完全相同的方法,该方法不存在。
试试这个:
for (PropertyDescriptor prop : Introspector.getBeanInfo(some_class.getClass()).getPropertyDescriptors()) {
if (prop.getName().equals(property_name)) {
prop.getWriteMethod().invoke(some_class, value)
}
}
或只使用Class.getMethods()
并搜索setter名称和一个arg。
答案 1 :(得分:0)
在一般情况下,这并不容易。你进入了Java规范的一部分,甚至大多数编译器都没有完全正确。
在这种特殊情况下(恰好是一个参数),您基本上必须找到一个参数类型与给定参数的类型兼容的方法。要么走向参数类型的继承层次结构(不要忘记多个接口!),要么遍历具有一个参数和所需名称的类的所有方法,并检查paramType.isAssignableFrom(argType)。
Spring中有一个实用程序类可能适用于大多数情况:
(不确定这是否是该课程的最新版本。)