I must miss something very fundamental. When I try to pass an array of any kind during a method invocation I get an error. However when I do it normally it works.
This is the complete code that fails
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
// Normal
MyClass.sayHello(new String[] {"StackOverflow"});
// Reflection
Method m = MyClass.class.getMethod("sayHello", String[].class);
m.invoke(null, new String[]{"StackOverflow"});
}
static class MyClass {
public static void sayHello(String[] args) {
System.out.println("Hello " + args[0]);
}
}
}
The Exception thrown
Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at Main.main(Main.java:11)
String...
does not work either btw.
The problem is that the second parameter to invoke
is meant to be an array of arguments - you're only specifying a single argument.
In most cases that would be okay as the second parameter of Method.invoke
is a varargs parameter, but as your argument is already an array compatible with Object[]
, the compiler isn't creating a wrapper array. I'd expect you to get a compile-time warning like this:
Main.java:11: warning: non-varargs call of varargs method with inexact argument type for
last parameter;
m.invoke(null, new String[]{"StackOverflow"});
^
cast to Object for a varargs call
cast to Object[] for a non-varargs call and to suppress this warning
You could either explicitly create an array wrapping the argument, or cast the argument to Object
so that the compiler needs to wrap it itself:
// Creates the wrapper array explicitly
m.invoke(null, new Object[] { new String[] { "StackOverflow" } });
or
// Compiler creates the wrapper array because the argument type is just Object
m.invoke(null, (Object) new String[] { "StackOverflow" });
See more on this question at Stackoverflow