Jonathon Faust
Jonathon Faust

Reputation: 12545

Java getMethod with superclass parameters in method

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?

Upvotes: 17

Views: 11504

Answers (4)

user207421
user207421

Reputation: 310883

See java.beans.Expression and java.beans.Statement.

Upvotes: 2

Bozho
Bozho

Reputation: 597076

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);
        }
    }
}

Upvotes: 21

Sean Owen
Sean Owen

Reputation: 66886

I'm guessing you want getDeclaredMethods(). Here is an example. You can dig through the list of methods and pick the one you want by name. Whether or not this is robust or a good idea is another question.

Upvotes: 1

Matt Ball
Matt Ball

Reputation: 359816

Instead of myList.getClass(), why not just pass in List.class? That is what your method is expecting.

Upvotes: 1

Related Questions