在Java中,当方法将baseclass作为参数时,使用Reflection调用方法无法找到方法

时间:2012-06-11 06:42:52

标签: java reflection

下面是代码片段,我试图使用REFLECTION调用usingClass方法。当我传递Child类型的对象时,直接调用usingClass()方法(没有反射)会起作用,但是当我尝试使用Reflection实现相同的操作时,它会抛出NoSuchMethodFoundException。想了解我是否遗漏了某些东西,或者这背后有什么逻辑?请帮忙

package Reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestMethodInvocation {

    /**
     * @param args
     */
    public static void main(String[] args) {
        TestMethodInvocation test = new TestMethodInvocation();
        Child child = new Child();
        Parent parent = (Parent)child;
        Class<? extends Parent> argClassType = parent.getClass();
        Class<? extends TestMethodInvocation>  thisClassType = test.getClass();

        test.usingClass(child);

        Method methodToCall;
        try {
            methodToCall = thisClassType.getDeclaredMethod("usingClass", argClassType);
            methodToCall.invoke(test, parent);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private void usingClass(Parent p){
        System.out.println("UsingClass: " + p.getClass());
    }


}

输出如下。

UsingClass: class Reflection.Child
java.lang.NoSuchMethodException: Reflection.TestMethodInvocation.usingClass(Reflection.Child)
    at java.lang.Class.getDeclaredMethod(Unknown Source)
    at Reflection.TestMethodInvocation.main(TestMethodInvocation.java:20)

2 个答案:

答案 0 :(得分:4)

您的代码不起作用的原因是getClass()是动态绑定的。转换为Parent不会影响对象的运行时类型,因此变量childparent包含相同的类对象。 除非您通过getGenericSuperclass()或类似的东西明确地查询您的父类的实例,否则您将不得不使用dystroy提到的静态方法。

答案 1 :(得分:1)

你应该使用

methodToCall = thisClassType.getDeclaredMethod("usingClass", Parent.class);

因为parent(它是Child)的精确确切类在运行时使用,并且保存它的变量的类型不会改变任何内容。

另一种(太沉重的)解决方法是:

Class<? extends Parent> argClassType2 = (new Parent()).getClass();
...
    methodToCall = thisClassType.getDeclaredMethod("usingClass", argClassType2);