I'm invoking some method of Class's instance using the method.invoke(instance, args...)
way but for each method inside the instance
, as the invoke
Javadoc rightly points out, each argument must be manually specified.
Thinking about Spring... how it could valorize parameters in controller's method behind the hood during HTTP calls? (but surely it does in a completely different way I think...)
I wonder if there's any way in Java to dynamically pass parameters in reflection (or not even reflection) without specifying each of them singularly.
EDIT
The instance class declaration is something like:
public class Something {
public void doSth(String par1, String par2, Integer par3) {
//....
}
public void doSthElse(String par1, Boolean par2) {
//....
}
public void doSthElseMore(Integer par1) {
//....
}
}
How I'm invoking each method:
...
for (Method method : instance.getDeclaredMethods()) {
Object[] array = //BL: build array of values to pass to the invoke method.
//1. doSth may be new Object[] {"abc", "def", 123}
//2. doSthElse iteration may be new Object[] {"abc", false}
//3. doSthElseMore iteration may be new Object[] {123}
return method.invoke(instance, array);
}
...
As shown above, each method inside Something
class (instance
) have a different number of parameters.
On each iteration, the array
have a different number of values to pass to the invoke
.
Actually as @Boris says all I had to do to complete my job was to convert each parameters to the correct type. In this way Java managed to invoke the correct method of the Something
class with the correct parameters types.
My project is a Vert.x
application using Vavr
and jodd
but the last return statement shows how I managed to solve.
public Object invokeMethod(Object service, Method method, RoutingContext routingContext) throws Exception {
MultiMap queryParams = routingContext.queryParams();
Map<String, String> pathParams = routingContext.pathParams();
Buffer body = routingContext.getBody();
// 1. type, 2. name, 3. value
List<Tuple3<Class<?>, String, Object>> list = List.empty();
for (Parameter par : method.getParameters()) {
ParamQuery paramQuery = par.getAnnotation(ParamQuery.class);
if (paramQuery != null) {
list = list.push(new Tuple3<Class<?>, String, Object>(par.getType(), paramQuery.value(),
queryParams.get(paramQuery.value())));
}
}
// TypeConverterManager used to "covnert" each object (String) from the HTTP call to the correct data type
return method.invoke(service, list.reverse()
.map(mapper -> TypeConverterManager.lookup(mapper._1()).convert(mapper._3())).toJavaArray());
}
However, this project can be found on GitHub
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