我有一个类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);
我得到"错误的参数数错误"。我错过了什么?
没关系。
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[]
。
让我们进一步了解一下东方和小鸟的意思…
这里可能让你感到困惑的是,Method.invoke(Object, Object...)
通常可以只接受参数"inline",可以这么说;当编译器看到类似someMethod.invoke(someObject, arg1, arg2)
的内容时,它隐式地创建一个数组new Object[]{arg1, arg2}
,然后将该数组传递给Method.invoke
。然后Method.invoke
将该数组的元素作为参数传递给您正在调用的方法。到目前为止,一切顺利。
但是当编译器看到像someMethod.invoke(someObject, someArray)
这样的东西时,它假设你已经把参数打包成一个数组;这样就不会再重新包装了。因此,Method.invoke
将尝试将someArray
的元素作为参数传递给您正在调用的方法,而不是将someArray
本身作为参数传递。
(这总是...
符号的工作方式;它接受(包含适当类型元素的数组,或 0个或多个适当类型的参数)
因此,正如orien和biaobiaoqi所说,您需要将parameters
重新包装到另一个数组new Object[] {parameters}
中,以便parameters
本身最终被传递到您的方法中。
明白了吗?
Method.invoke
方法接受接收方法调用的对象和该方法的参数数组。因为你的方法只有一个参数,所以数组的大小必须是1
。
尝试创建一个大小为1
:
someMethod.invoke(anObject, new Object[] {parameters});
注意,这个数组中的一个值可以是null
。这将模拟anObject.someMethod(null)
invoke
的参数为Object
的数组;你的参数应该是一个Object[]
,包含你传递给someMethod
的Object[]
。
您不需要立即创建一个数组来完成此操作,因为invoke
签名是invoke(Object, Object...)
,但在您的情况下,您试图传递一个空数组。如果你想传入null:
Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);
然而,其他答案最终是正确的:您需要传入一个包含每个方法参数的条目的Object[]
。
try this:
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});
}
}