29

我有一个类AClass和一个someMethodObject数组作为参数的方法。

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

在 main 中,当我尝试在我创建的对象上调用此方法并将对象数组作为此方法的参数时

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);

注意调用方法的第二个参数。它Object[]本身,你的方法的参数类型Object[]也是。

于 2011-11-18T22:19:27.030 回答
16

稍微扩展一下东方和标标旗的说法。. .

在这里可能让您感到困惑的是,Method.invoke(Object, Object...)通常可以将参数“内联”,可以这么说;当编译器看到类似的东西时someMethod.invoke(someObject, arg1, arg2),它会隐式创建一个数组new Object[]{arg1, arg2},然后将该数组传递给Method.invoke. Method.invoke然后将该数组的元素作为参数传递给您正在调用的方法。到目前为止,一切都很好。

但是当编译器看到类似的东西时someMethod.invoke(someObject, someArray),它假定您已经将参数打包到一个数组中;所以它不会再次重新包装它们。因此 thenMethod.invoke将尝试将 的元素作为someArray参数传递给您正在调用的方法,而不是将someArray 其自身作为参数传递。

(这始终是...符号的工作方式;它接受包含适当类型元素的数组,或者零个多个适当类型的参数。)

因此,正如 orien 和 biobiaoqi 所说,您需要将您的重新包装parameters到一个额外的数组中new Object[] {parameters},以便parameters最终将其本身传递到您的方法中。

那有意义吗?

于 2011-11-18T22:28:13.730 回答
10

Method.invoke方法接受对象以接收方法调用和该方法的参数数组。由于您的方法采用一个参数,因此给定数组的大小必须为1.

尝试使用 size 创建一个新数组1

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

请注意,此数组中的一个值可以是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 自动生成代码的反射 API 版本得到的:

$ 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 回答