29

パラメータとして配列を取得するクラスAClassとメソッドがあります。someMethodObject

public class AClass {
    public void someMethod(Object[] parameters) {
    }
}

主に、作成したオブジェクトでこのメソッドを呼び出して、このメソッドのパラメーターとしてオブジェクト配列を指定しようとすると、

Object[] parameters; // lets say this object array is null
Class class = Class.forName("AClass");
Object anObject = class.newInstance();

Method someMethod = class.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, parameters);

「引数の数が間違っています」というエラーが発生します。私は何が欠けていますか?

4

5 に答える 5

27

それで大丈夫です。

Object[] parameters = {new Object()}; // lets say this object array is null
Class clas = Class.forName("AClass");
Object anObject = clas.newInstance();

Object[] param = {parameters};

Method someMethod = clas.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, param);

invokeメソッドの2番目のパラメーターに注意してください。それObject[]自体であり、メソッドの引数タイプObject[]も同様です。

于 2011-11-18T22:19:27.030 に答える
16

orienとbiaobiaoqiが言っていることを少し拡張します。。。

ここでおそらく混乱しているのはMethod.invoke(Object, Object...)、いわば「インライン」で引数を取ることができるということです。コンパイラがのようなものsomeMethod.invoke(someObject, arg1, arg2)を検出すると、暗黙的に配列を作成し、new Object[]{arg1, arg2}その配列をに渡しMethod.invokeます。Method.invoke次に、その配列の要素を、呼び出しているメソッドへの引数として渡します。ここまでは順調ですね。

ただし、コンパイラがのようなものsomeMethod.invoke(someObject, someArray)を検出すると、引数がすでに配列にパッケージ化されていると見なされます。そのため、それらを再度パッケージ化することはありません。したがって、引数としてそれ自体を渡すのではなく、呼び出しているメソッドに引数としての要素Method.invoke渡そうとします。someArraysomeArray

(これは常に表記法の仕組みです。適切なタイプの要素を含む配列、または適切なタイプの0個以上の引数を...受け入れます。)

したがって、orienとbiaobiaoqiが言ったようparametersに、追加の配列に再ラップする必要がありますnew Object[] {parameters}。そうすれば、parametersそれ自体がメソッドに渡されることになります。

それは理にかなっていますか?

于 2011-11-18T22:28:13.730 に答える
10

このMethod.invokeメソッドは、オブジェクトを受け取り、メソッド呼び出しとメソッドへの引数の配列を受け取ります。メソッドは1つの引数を取るため、指定された配列のサイズは。でなければなりません1

サイズの新しい配列を作成してみてください1

someMethod.invoke(anObject, new Object[] {parameters});

この配列の1つの値は。である可能性があることに注意してくださいnull。これはシミュレートしますanObject.someMethod(null)

于 2011-11-18T22:17:41.343 に答える
4

toのパラメータは;invokeの配列です。Objectパラメータは、に渡すをObject[] 含むものである必要があります。Object[]someMethod

invoke署名はであるため、これを行うために即時配列を作成する必要はありませんinvoke(Object, Object...)が、あなたの場合は空の配列を渡そうとしています。nullを渡したい場合:

Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);

ただし、最終的には、他の答えは正しいです。各メソッドパラメータのObject[]エントリを含むものを渡す必要があります。

于 2011-11-18T22:16:38.960 に答える
1

これを試して:

    someMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});

dp4jを使用してコードのReflectionAPIバージョンを自動的に生成することで取得しました。

$ javac -cp dp4j-1.2-jar-with-dependencies.jar -Averbose=true AClass.java
AClass.java:10: Note: 
import com.dp4j.*;

public class AClass {

    public AClass() {
        super();
    }

    public void someMethod(Object[] parameters) {
    }

    @Reflect(all = true)
    public static void main(String... args) throws ... {
        Object[] parameters = null;
        ...
        AClass anObject;
        anObject = (.AClass)aClassConstructor.newInstance();
        java.lang.reflect.Method someMethodWithArrayMethod = null;
        someMethodWithArrayMethod = Class.forName("AClass").getDeclaredMethod("someMethod", .java.lang.Object[].class);
        someMethodWithArrayMethod.setAccessible(true);
        someMethodWithArrayMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
    }
}
于 2011-11-19T11:40:30.273 に答える