调用方法时出现参数数量错误

问题描述 投票:0回答:5

我有类

AClass
和一个方法
someMethod
,它获取
Object
数组作为参数。

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

我收到“参数数量错误错误”。 我缺少什么?

java reflection illegalargumentexception
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方法的第二个参数。它是

Object[]
本身,并且你的方法的参数类型也是
Object[]


20
投票

稍微扩展一下 Orien 和 biabieqi 所说的内容。 。 .

这里可能让您感到困惑的是,

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

但是,当编译器看到类似

someMethod.invoke(someObject, someArray)
的内容时,它会假设您已经将参数打包到数组中;所以它不会再次重新打包它们。因此
Method.invoke
将尝试将 someArray
elements
作为参数传递给您正在调用的方法,而不是传递
someArray
itself 作为参数。

(这始终是

...
表示法的工作方式;它接受 either 包含适当类型元素的数组,or 零个或多个适当类型的参数。)

因此,正如 orien 和 biaobiaoqi 所说,一种解决方案是将您的

parameters
重新包装到另一个数组
new Object[] {parameters}
中,以便
parameters
本身最终被传递到您的方法中。 (另一种解决方案是编写
(Object)parameters
,显式从
Object[]
向上转换为
Object
,这样编译器就不会将其视为数组,并会为您包装它。)

这有道理吗?


11
投票

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

尝试创建一个大小为

1
:

的新数组
someMethod.invoke(anObject, new Object[] {parameters});

请注意,该数组中的一个值可以是

null
。这将模拟
anObject.someMethod(null)


4
投票

invoke
的参数是
Object
的数组;您的参数应该是一个
Object[]
包含 您要传递给
Object[]
someMethod

您不需要创建一个立即数组来执行此操作,因为

invoke
签名是
invoke(Object, Object...)
,但在您的情况下,您尝试传递一个 数组。如果你想传入null:

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

最终,其他答案是正确的:您需要传入一个

Object[]
,其中包含 每个方法参数的条目。


1
投票

试试这个:

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

我通过使用 dp4j 自动生成代码的 Reflection 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});
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.