我有以下界面:
interface Foo {
void bar(String a, int b);
}
我想反思地调用Foo.bar
(在Foo的实现上)。 但是,参数在数组中,我不知道它的大小。
以下不起作用:
void gee(Foo someFoo, Method bar, Object[] args) {
bar.invoke(someFoo, args);
}
这不起作用,因为编译器将args
作为单个参数进行了威胁,并且数组没有“扩展”到vararg,而是在一个包含单个元素的数组中(内部)包装,即
@Test
public void varArgTest() {
assertTrue(varArgFoo(new Object[] {1, 2}) == 1);
}
private static <T> int varArgFoo(T... arg) {
return arg.length;
}
在这种情况下如何调用Method.invoke()
以便将数组作为vararg进行威胁?
或者更一般的问题:当参数在数组中时我如何调用vararg方法我不知道数组的大小直到运行时。
答案 0 :(得分:10)
vararg参数实际上是一个带有一些额外元数据的数组参数。因此,当您使用Method.invoke
时,需要将数组包装在另一个数组中:
Object[] varargs = new Object[] { 10, 20 };
Object argumentArray = new Object[] { varargs };
method.invoke(target, argumentArray);
答案 1 :(得分:3)
以下不起作用:
是的。
这不起作用,因为args被编译器威胁为a 单个参数和数组没有“扩展”到vararg但是 用单个元素包裹(内部)在另一个数组中,即
使用您提供的代码,数组的元素应该成为varargs参数。如果您没有这样做,要么您没有显示您的实际代码,要么显示其他错误。
如果您的args
变量不具有数组类型(例如,它是类型Object
),那么可能会发生这种情况。但那不是你要展示的代码。
或者,如果您有一些“额外”参数未显示(例如,您尝试执行bar.invoke(someFoo, firstArg, args);
之类的操作,那么它将不会展开args
,因为您正在使用varargs已经形成了。