Invoking method using reflection / Converting List to Var Args
I have a list of parameters and I have the method name. I want to invoke the method using reflection. When I checked the java doc for Method.invoke its like Method.invoke(object o, Object args...) . I know what to pass for the first paramter (i.e instance on which method to be invoked if its instance method) and args is the parameters for the method.
But now I have have the list which contains values which are to be passed to the method.
Say for example: I want to invoke method ClassName.methodName(String , int, int) and I have a List which contains {val1, 3, 4}.
Using reflection it may be like Method.invoke (classNameInstance, ??????).开发者_Go百科 But I am not sure how to convert a list of arguments to varargs and pass.
One way may be If i know that list size is 3 then I may write Method.invoke (classNameInstance, list.get(0), list.get(1), list.get(2)).
But some of the methods which I want to dynamically invoke take 0 to 12 arguments. So it doesn't look "good" to create switch case and write 12 cases. Each will check with number of parameters and build the separate call with parameters.
Any way to go about this except from using switch case?
Any help will be greatly appreciated.
The Notation Object... means nothing more than Object[]. It is just syntactic sugar for an Arraynotation. Pass an Array and it will work.
EDITED: this is a more general approach that works for any type of vararg params:
Class<?> c = int.class;
Object array = Array.newInstance(c, list.size());
for (int i = 0; i < list.size(); i++)
Array.set(array, i, list.get(i));
Test.class.getDeclaredMethod("test", array.getClass()).invoke(
new Test(), new Object[] { array });
void m(X...p)
has the same signature as void m(X[] p)
. You cannot declare both in the same class.
Here is how to invoke them using reflection (primitives and non-primitives):
import java.util.*;
import java.lang.reflect.*;
class Test
{
public static void main(String[] args) throws Exception
{
List<Integer> list = new ArrayList<Integer>();
list.add(1); list.add(2); list.add(3);
Test.class.getDeclaredMethod("test", Integer[].class).invoke(
new Test(), new Object[] { list.toArray(new Integer[0]) });
int[] params = new int[list.size()];
for (int i = 0; i < params.length; i++) params[i] = list.get(i);
Test.class.getDeclaredMethod("test", int[].class).invoke(
new Test(), new Object[] { params });
}
public void test(int ... i) { System.out.println("int[]: " + i[0] + ", " + i[1] + ", " + i[2]); }
public void test(Integer... i) { System.out.println("Integer[]" + Arrays.asList(i)); }
}
Varargs is really just an array.
The method can be retrieved like this, assuming it takes int...
args:
Method method = MyClass.class.getMethod("someMethod", int[].class);
method.invoke(myInstance, argumentsList.toArray());
精彩评论