Reflection: How to Invoke Method With Parameters

Reflection: How to Invoke Method with parameters

Change "methodInfo" to "classInstance", just like in the call with the null parameter array.

  result = methodInfo.Invoke(classInstance, parametersArray);

Invoke Method with reflection pass through parameters and receive a return value

Have a look at the signature of MethodInfo.Invoke

public object Invoke(
object obj,
object[] parameters
)

You need to pass the parameters of the method in the parameters object[]. Note that the method returns an object, you just need to cast it to the result type.

A call to TestString should look like this:

var parameters = new object[]{"A string", 10, 'a'};
string result = (string) t.GetMethod("Print").Invoke(t, parameters);

using reflection to invoke methods which takes different parameters

The problem here is in the line

result = this.methodTocall.invoke(null, new Object[]{args});

When you pass arguments to the method, you wrap them in another Object[], which is a) unnecessary and, when args contains multiple arguments (like the string and the int from your second method call), hides those arguments in the Object array, making them appear as one parameter. That is why you get the error.

Solve it by using the following changes:

result = this.methodTocall.invoke(null, args);

Then change your main method to this:

String[] a = new String[]{"H","E","L","L","O"};
MethodCalling mc = new MethodCalling("wat.SizeChecker");
mc.setMethod("isTooBig", Comparable[].class);
/* change here: place the single parameter into a parameter array */
Boolean result1 = (Boolean) mc.callMethod(new Object[]{a});
System.out.println("too big="+result1);

mc.setMethod("isCorrectLength",Comparable[].class, int.class);
/* since the callMethod accepts varargs, these are automatically placed in an Object[] */
Boolean result2 = (Boolean) mc.callMethod(a, 5);
System.out.println("length is 5="+result2);

How to invoke with reflection a method that accepts a Func parameter?

There is indeed no conversion from method groups to object, but there are conversions from method groups to compatible delegate types (method group conversions), and there are also conversions from delegate types to object. So you can first convert the method group to Func<Expression, Expression, BinaryExpression> with a cast, then it can be implicitly converted to object:

someMethodInfo.Invoke(null, new object[] { (Func<Expression, Expression, BinaryExpression>)Expression.Subtract });

How to use reflection to invoke a method with primitive arguments?

When arguments such as 10 or 10.0f are passed into the method, they are automatically wrapped, because the parameter type is Object....

Therefore, you need to check for these wrapper types and unwrap them. Your for loop can look like this:

for(int i = 0; i < args.length; i++) {
if (args[i].getClass() == Integer.class) {
classes[i] = int.class;
} else if (args[i].getClass() == Float.class) {
classes[i] = float.class;
} else if (args[i].getClass() == Double.class) {
classes[i] = double.class;
} else {
classes[i] = args[i].getClass();
}
}

I have only added 3 cases here, you can add the other 5 yourself.

This means that you can't call methods with wrapper type arguments now. If you want to call those as well, you need to

  1. unwrap all the wrapper types
  2. try to find a method with those non-wrapper types
  3. If not found, wrap them up again
  4. find the a method using the wrapper types.

Edit:

As Holger suggested in the comments, you can also let the JVM find a suitable method for you, by using

new Statement(this, methodName, args).execute();

Docs for the Statement class.

Invoke method by reflection with dynamic parameters

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

How do I invoke a Java method when given the method name as a string?

Coding from the hip, it would be something like:

java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) { ... }
catch (NoSuchMethodException e) { ... }

The parameters identify the very specific method you need (if there are several overloaded available, if the method has no arguments, only give methodName).

Then you invoke that method by calling

try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) { ... }
catch (IllegalAccessException e) { ... }
catch (InvocationTargetException e) { ... }

Again, leave out the arguments in .invoke, if you don't have any. But yeah. Read about Java Reflection

How invoke method for a method by default value for parameters by reflection

You can use ParameterInfo.HasDefaultValue and ParameterInfo.DefaultValue to detect this. You'd need to check whether the number of arguments you've been given is equal to the number of parameters in the method, and then find the ones with default values and extract those default values.

For example:

var parameters = method.GetParameters();
object[] args = new object[parameters.Length];
for (int i = 0; i < args.Length; i++)
{
if (i < providedArgs.Length)
{
args[i] = providedArgs[i];
}
else if (parameters[i].HasDefaultValue)
{
args[i] = parameters[i].DefaultValue;
}
else
{
throw new ArgumentException("Not enough arguments provided");
}
}
method.Invoke(method.IsStatic ? null : this, args);


Related Topics



Leave a reply



Submit