Reputation: 29493
I have the following interface:
interface Foo {
void bar(String a, int b);
}
I want to invoke Foo.bar
(on an implementation of Foo) reflectively. However, the arguments are in array and i do not know the size of it.
The following does not work:
void gee(Foo someFoo, Method bar, Object[] args) {
bar.invoke(someFoo, args);
}
That does not work because args
is threated by the compiler as a single argument and the array is not "expanded" to vararg but is wrapped (internally) in one more array with single element, i.e.
@Test
public void varArgTest() {
assertTrue(varArgFoo(new Object[] {1, 2}) == 1);
}
private static <T> int varArgFoo(T... arg) {
return arg.length;
}
How can i call Method.invoke()
in this case so that the array is threated as vararg?
Or more general question: how do i call vararg method when arguments are in array i do not knew the size of the array until runtime.
Upvotes: 3
Views: 4797
Reputation: 122489
The following does not work:
Yes it does.
That does not work because args is threated by the compiler as a single argument and the array is not "expanded" to vararg but is wrapped (internally) in one more array with single element, i.e.
With the code you have presented, the array's elements should become the varargs arguments. If that's not happening for you, either you are not showing your actual code, or something else is wrong.
If somehow your args
variable does not have an array type (e.g. it is typed Object
), then that could happen. But that is not the code you're showing.
Or if you have some "additional" arguments you are not showing (e.g. you are trying to do something like bar.invoke(someFoo, firstArg, args);
, then it will not expand args
, because you are using the method in the varargs form already.
Upvotes: 3
Reputation: 1502835
A vararg parameter is actually an array parameter with a bit of extra metadata. So when you use Method.invoke
, you need to wrap the array in another array:
Object[] varargs = new Object[] { 10, 20 };
Object argumentArray = new Object[] { varargs };
method.invoke(target, argumentArray);
Upvotes: 10