I have a problem trying to solve a situation, when I use Java Reflection API to invoke a method that accepts a variable number of parameters. Every time I try to do that I get an "NoSuchMethodException".
My declaration of method to invoke:
public void AddShow(String movieName, String cinemaName, String... days) {
}
And the code for the method that does the invocation:
public void Exec(String command){
try {
String[] words = command.split(" ");
String commandName = words[0];
Class<? extends UserInterface> thisClass = (Class<? extends UserInterface>)getClass();
Class<String>[] par = new Class[words.length-1];
String[] params = new String[words.length-1];
for(int i = 1; i< words.length; i++){
params[i-1] = words[i];
try {
par[i-1] = (Class<String>) Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
System.out.println("If this shows up, something is siriously wrong... Waht have you done?!");
}
}
Method method;
if(par.length != 0) {
method = thisClass.getMethod(commandName, par);
method.invoke(new UserInterface(CinemaDb), (Object[])params);
} else {
method = thisClass.getMethod(commandName);
method.invoke(new UserInterface(CinemaDb));
}
} catch (SecurityException e) {
System.out.println("Security error, sry again.");
} catch (NoSuchMethodException e) {
System.out.println("Wrong command, try again (check the parameters)!");
} catch (IllegalAccessException e) {
System.out.println("You don't have access rights, try again.");
} catch (IllegalArgumentException e) {
System.out.println("Wrong arguments, try again.");
} catch (InvocationTargetException e) {
System.out.println("Invocation error, try again.");
}
}
If you know how can I change my Exec method to solve this problem, I will be really grateful.
Thanks!
varargs in Java are implemented via arrays, so the parameters are String.class, String.class, and String[].class
.
The varargs part is represented as String[]
after compilation, so use String[].class
In your case it will be a bit harder, since you can't know exactly how many of the arguments there are before the varargs. So if you invoke showFoo str1 str2 str3 str4
you can't know how many string arguments there are before the varargs.
So you can put a delimiter in your command string, which will tell the parser where to add the String[].class
. Another option is to simply call getMethods()
and get the required method only by its name (iterate and compare the names). But you won't be able to use overloading.
That said, I don't think it is a really good idea to have such a specially-formatted string for reflective executions (unless it comes from an external system, but then it might be a security issue)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With