Simple question, how make this code working ?
public class T {
public static void main(String[] args) throws Exception {
new T().m();
}
Test.class.getDeclaredMethod("foo", String[].class);
works. The problem is that getMethod(..)
only searches the public
methods. From the javadoc:
Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object.
Update: After successfully getting the method, you can invoke it using:
m.invoke(this, new Object[] {new String[] {"a", "s", "d"}});
that is - create a new Object
array with one element - the String
array. With your variable names it would look like:
m.invoke(this, new Object[] {a});
//prior to edit:
Your problem is the fact that getMethod
looks for a public
member.
From the Class.getMethod (emphasis mine):
Returns a
Method
object that reflects the specified public member method of the class or interface represented by this Class object
So you have two options:
public void foo(String... s)
and use getMethod
getDeclaredMethod
insteadNote that the same difference exists for getField/s
vs getDeclaredField/s
and getConstructor/s
vs getDeclaredConstructor/s
.
//invoke
problem
This is particularly nasty, but what happens is that invoke(Object obj, Object... args)
makes it tricky if you need to pass an array of reference type as an only argument, because it is cast-able to Object[]
, even though it should be wrapped inside a new Object[1]
instead.
You can do:
m.invoke(this, new Object[] {a}); // Bohzo's solution
This bypasses the vararg mechanism. More succinctly you can also do:
m.invoke(this, (Object) a);
The cast to Object
makes the vararg mechanism do the work of creating the array for you.
The trick is also needed when passing a null
as an argument to varargs, and has nothing to do with reflection.
public void foo(String... ss) {
System.out.println(ss[0]);
}
foo(null); // causes NullPointerException
foo((String) null); // prints "null"