Java getMethod с параметрами суперкласса в методе - PullRequest
15 голосов
/ 05 апреля 2010

Дано:

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?

Ответы [ 4 ]

19 голосов
/ 05 апреля 2010

Если вы знаете, что тип 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 голосов
/ 06 апреля 2010

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

1 голос
/ 05 апреля 2010

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

1 голос
/ 05 апреля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...