Reputation: 8350
How do I recreate a method invocation? when all I've got is the list of methods, obtained by getDeclaredMethods()
, and converted into a HashMap<String,Method>
and a list of its parameters' Classes, obtained by getParameterTypes()
.
Suppose I get a string from the user and I want to invoke it:
"print(3,"Hello World!",true,2.4f)"
And the method print(int,String,boolean,float)
is part of the getMethods() array. I'm having trouble to figure out how do I compose the invocation. So far this is what I got:
private static final Pattern functionCall = Pattern.compile(String.format("^%s\\(%s?\\)$", "(\\w+)", "(.*)"));
if( (m = functionCall.matcher(line)).find() ) {
String function = m.group(1); // in this example = "print"
String arguments = m.group(2); // in this example = "3,\\"Hello World!\\",true,2.4f"
if( methods.containsKey(function) ) {
Method method = methods.get(function);
Class<?>[] paramsExpected = method.getParameterTypes();
String [] paramsActual = arguments.split(",");
if( paramsExpected.length != paramsActual.length ) {
throw new IllegalArgumentException(function + ": bad number of arguments");
}
for( Class<?> param: paramsExpected) {
???????
}
method.invoke(context, ??????);
To be perfectly clear, I don't know in advance what string the user will input, I have to check it against the available methods and their parameters, and if I find it, then I have to invoke it with the parameters supplied by the user.
Upvotes: 1
Views: 127
Reputation: 21010
This what you need to do. One option is to use the ConverterUtils.convert method of BeanUtils to convert string to object of specific type. This will work for built in types.
Object[] args = new Object[paramsExpected.length];
int i = 0;
for( Class<?> param: paramsExpected) {
args[i] = convertStringToType(paramsActual[i], param);
i = i +1;
}
method.invoke(context, args);
Object convertStringToType(String input, Class<?> type) {
return ConverterUtils.convert(input,type);
}
Upvotes: 2