Java反射方法调用错误

时间:2012-08-15 20:31:10

标签: java api reflection override

我正在制作一种测试程序,能够覆盖我在java中创建的api类中的方法,但是当我尝试从另一个类调用一个方法时,我遇到了一个奇怪的错误... < / p>

这是主要的“组件类”:

 package st.cmp;

 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;

 public class Component {

public class Overrider{
    Class<?> source;
    Class<?>[] overs;
    String name;
    public Overrider(Class<?> s,String n,Class<?>[] o){
        source=s;
        overs=o;
        name=n;
    }
    public Object call(Object[] param){
        try {
            return source.getMethod(name, overs).invoke(this, param);
        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
};


public HashMap<String,Component> cmps;
public HashMap<String,Overrider> over;

public Component(){
    cmps=new HashMap<String,Component>();
    over=new HashMap<String, Overrider>();
}

public void registerComponent(String nm,Component cm){
    cmps.put(nm,cm);
}
public Component getComponent(String nm){
    return cmps.get(nm);
}

public void override(Class<?> cl,String name,Class<?>[] param){

        over.put(name,new Overrider(cl,name,param));

}

public Object call(String mnm,Object[] a){
    Overrider ov=over.get(mnm);
    if(ov!=null){
        ov.call(a);
    }

    Class<?>[] abc=new Class<?>[a.length];

    for(int i=0;i<a.length;i++){
        abc[i]=a[i].getClass();
    }

        try {
            return this.getClass().getDeclaredMethod(mnm, abc).invoke(this,a);
        } catch (IllegalAccessException | IllegalArgumentException
                | InvocationTargetException | NoSuchMethodException
                | SecurityException e) {
            // TODO Auto-generated catch block
            try {
                this.getClass().getDeclaredMethod(mnm, abc).invoke(this,a);
            } catch (IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | NoSuchMethodException
                    | SecurityException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }


    return null;
}

public void test(String a){
    System.out.print(a);
}

public int add(Integer a,Integer b){
    return a+b;
}
 }

这是主要的课程:

package st;

 import st.cmp.Component;

 public class Start {
public static void main(String[] args)
{
    new Start().start();
}
public void start(){
    Component a=new Component();
    a.call("test",new Object[]{a.call("add",new Object[]{1,5}).toString()});

    a.override(this.getClass(), "add", new Class<?>[]{Integer.class,Integer.class});

    a.call("test",new Object[]{a.call("add",new Object[]{1,5}).toString()});
}
public int add(Integer a,Integer b){
    return a*b;
}

 }

启动程序时出现此错误:

6java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at st.cmp.Component$Overrider.call(Component.java:22)
    at st.cmp.Component.call(Component.java:64)
    at st.Start.start(Start.java:16)
    at st.Start.main(Start.java:8)
6

任何人都可以帮助我吗?

它说“对象不是声明类的实例”......但它指的是什么“对象”?

2 个答案:

答案 0 :(得分:2)

Start课程中,您正在调用Component.override()方法:

//         v--- This is the Class Object
a.override(this.getClass(), "add", new Class<?>[]{Integer.class,Integer.class});

a的类型为Component。您正在传递this.getClass(),它是Start的Class对象。然后在override()

//                          v--- Class object gets passed along here
over.put(name,new Overrider(cl,name,param));

您正在创建一个新的Overrider,并将Start的Class对象提供给构造函数,该构造函数将Class<?> source;字段设置为Start Class对象。然后,当您调用Overrider.call()方法时,它会执行以下操作:

//     v--- and finally invoked here
return source.getMethod(name, overs).invoke(this, param);

并传递invoke()一个this Component的实例,而sourceStart的一个Class对象。在这一行中,“source”和“this”需要是同一个类,但StartComponent不是。

答案 1 :(得分:0)

你的代码很复杂,但这是我的帮助。如果您有这样的一行:

klass.getMethod(name).invoke(obj)

然后错误表明obj不是klass的实例。