在数组中的参数时调用Method.invoke()

时间:2012-12-28 15:56:21

标签: java reflection variadic-functions

我有以下界面:

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方法我不知道数组的大小直到运行时。

2 个答案:

答案 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已经形成了。