Java getMethod с параметрами суперкласса в методе

Дано:

class A
{
    public void m(List l) { ... }
}

Скажем, я хочу вызвать метод m с отражением, передав ArrayList в качестве параметра m:

List myList = new ArrayList();
A a = new A();
Method method = A.class.getMethod("m", new Class[] { myList.getClass() });
method.invoke(a, Object[] { myList });

В строке getMethod в строке 3 будет выбрано NoSuchMethodException, потому что тип времени выполнения myList - это ArrayList, а не List.

Существует ли общий общий способ, который не требует знания типов параметров класса A?

Ответы

Ответ 1

Если вам известен тип List, используйте List.class в качестве аргумента.

Если вы не знаете тип заранее, представьте, что у вас есть:

public void m(List l) {
 // all lists
}

public void m(ArrayList l) {
  // only array lists
}

Какой метод должен вызывать отражение, если есть какой-либо автоматический способ?

Если вы хотите, вы можете использовать Class.getInterfaces() или Class.getSuperclass(), но это зависит от конкретного случая.

Что вы можете сделать здесь:

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

Ответ 2

См. java.beans.Expression и java.beans.Statement.

Ответ 3

Вместо myList.getClass(), почему бы просто не пройти в List.class? Это то, что ожидает ваш метод.

Ответ 4

Я предполагаю, что вы хотите getDeclaredMethods(). Вот пример . Вы можете просмотреть список методов и выбрать тот, который вы хотите по имени. Независимо от того, является ли это надежным или хорошая идея, это еще один вопрос.