1

Javaで作成しているAPIのクラスのメソッドをオーバーライドできるように、一種のテストプログラムを作成していますが、別のクラスからメソッドを呼び出そうとすると奇妙なエラーが発生します...

メインの「コンポーネント クラス」は次のとおりです。

 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

誰でも私を助けることができますか?

「オブジェクトは宣言クラスのインスタンスではありません」と表示されています...しかし、それが参照している「オブジェクト」は何ですか?

4

2 に答える 2

2

あなたのStartクラスでは、メソッドを呼び出していますComponent.override()

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

aは のタイプですComponentthis.getClass()の Class オブジェクトであるを渡しますStart。次にoverride()

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

新しい を作成し、フィールドをClass オブジェクトに設定するコンストラクターにOverriderClass オブジェクトを渡します。次に、メソッドを呼び出すと、次のようになります。StartClass<?> source;StartOverrider.call()

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

そしてのインスタンスであるinvoke()aを渡しますが、は の Class オブジェクトです。この行では、「source」と「this」は同じクラスである必要がありますが、そうではありません。thisComponentsourceStartStartComponent

于 2012-08-15T20:41:59.940 に答える
0

あなたのコードはかなり複雑ですが、これは私の助けです。次のような行がある場合:

klass.getMethod(name).invoke(obj)

objのインスタンスではないというエラーが表示されますklass

于 2012-08-15T20:37:05.713 に答える