使用子类作为方法参数调用getMethod

时间:2013-11-17 09:06:25

标签: java reflection subclass invoke superclass

是否可以调用参数对象或参数类是子类的方法,并且方法本身将超类作为参数?

我尝试使用抽象类问题的具体实现来调用此方法public void setNewProblem(Problem problem);。不幸的是,我得到NoSuchMethodException例外。

我这样调用调用:

Method method = model.getClass().getMethod("set" + propertyName, new Class[] { newValue.getClass() });
method.invoke(model, newValue);

如果我将newValue.getClass()更改为Problem.class,一切正常。知道如何将子类传递给public void setNewProblem(Problem problem);吗?

3 个答案:

答案 0 :(得分:3)

你必须要求确切的类型。这是因为您可以拥有多个可能的重载方法,并且需要准确了解您想要的内容。

所以你可以用子类调用,但是你不能在不在那里的情况下要求子类。

你可以做的是查看所有方法并找到匹配。

如果您需要的只是属性的setter或getter,我建议您查看BeanIntrospector,它会找到该属性的所有属性和getter / setter方法。

答案 1 :(得分:1)

问题是newValue.getClass()是声明方法中类的子类。

来自Class.getMethod

  

要在类C中查找匹配方法:如果C只声明一个   具有指定名称和完全相同的正式的公共方法   参数类型,即反映的方法。

你可以在继承链上工作,直到它起作用:

Method getMethod(Class c1, Class c2) {
    if(c2.getSuperClass() == null) {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    }
    try {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    } catch(NoSuchMethodException e) {
        return getMethod(c1, c2.getSuperClass());
    }
}

用法:

Method method = getMethod(model.getClass(), newValue.getClass());

但是,我毫不犹豫地建议这样做,因为它没有涵盖100%的情况(例如正式参数类是一个接口),而你这样做的方式很糟糕。

答案 2 :(得分:1)

当您致电Class.getMethod()时,您必须正确指定正式参数类型。不是您计划提供的实际参数的类型。您必须准确匹配相关方法声明中的内容。

"The parameterTypes parameter is an array of Class objects that identify the method's formal parameter types, in declared order."