Given:
class A
{
    public void m(List l) { ... }
}
Let's say I want to invoke method m with reflection, passing an ArrayList as the parameter to m:
List myList = new ArrayList();
A a = new A();
Method method = A.class.getMethod("m", new Class[] { myList.getClass() });
method.invoke(a, Object[] { myList });
The getMethod on line 3 will throw NoSuchMethodException because the runtime type of myList is ArrayList, not List.
Is there a good generic way around this that doesn't require knowledge of class A's parameter types?
If you know the type is List, then use List.class as argument.
If you don't know the type in advance, imagine you have:
public void m(List l) {
 // all lists
}
public void m(ArrayList l) {
  // only array lists
}
Which method should the reflection invoke, if there is any automatic way?
If you want, you can use Class.getInterfaces() or Class.getSuperclass() but this is case-specific.
What you can do here is:
public void invoke(Object targetObject, Object[] parameters,
        String methodName) {
    for (Method method : targetObject.getClass().getMethods()) {
        if (!method.getName().equals(methodName)) {
            continue;
        }
        Class<?>[] parameterTypes = method.getParameterTypes();
        boolean matches = true;
        for (int i = 0; i < parameterTypes.length; i++) {
            if (!parameterTypes[i].isAssignableFrom(parameters[i]
                    .getClass())) {
                matches = false;
                break;
            }
        }
        if (matches) {
            // obtain a Class[] based on the passed arguments as Object[]
            method.invoke(targetObject, parametersClasses);
        }
    }
}
                        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