Данный:
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, не Список.
Существует ли хороший универсальный путь вокруг этого, которое не требует знания типов параметра класса A?
Если вы знаете, что тип 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);
}
}
}
Думаю, вам нужен getDeclaredMethods ()
. Вот пример . Вы можете покопаться в списке методов и выбрать по имени тот, который вам нужен. Другой вопрос, насколько это надежно или хорошая идея.
Вместо myList.getClass()
, почему бы просто не передать List.class
? Это то, что ожидает ваш метод.