3

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.

2
  • Your question cannot be deleted anymore, too many SO users have posted answers and otherwise spent attention on it. You can flag a moderator but you'll need to come up with a really good reason to get them to delete it for you. I'd recommend some kind of national security emergency. Commented Dec 30, 2012 at 23:24
  • @Hans Passant I did flag it, but no moderator responded. I changed the title to do not appear in the searches, since the question is misleading ... even the most voted answer is wrong and misleading Commented Dec 31, 2012 at 0:34

2 Answers 2

10

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);
Sign up to request clarification or add additional context in comments.

2 Comments

From the question, the OP sounds like they have the opposite problem, i.e. they want it not wrapped but it is wrapped
@newacct: It's far from clear - but the way I've described it is the only way I can understand things going wrong...
3

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.

1 Comment

You are right, in my test case, by mistake i had assertFalse instead assertTrue. But i can not delete the question. I flagged it so that moderator would delete it, but did not happen yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.