Рассмотрите следующий отрывок:
public class ReflectionTest {
public static void main(String[] args) {
ReflectionTest test = new ReflectionTest();
String object = new String("Hello!");
// 1. String is accepted as an Object
test.print(object);
// 2. The appropriate method is not found with String.class
try {
java.lang.reflect.Method print
= test.getClass().getMethod("print", object.getClass());
print.invoke(test, object);
} catch (Exception ex) {
ex.printStackTrace(); // NoSuchMethodException!
}
}
public void print(Object object) {
System.out.println(object.toString());
}
}
getMethod()
очевидно, не знает это a String
мог питаться к методу, который ожидает Object
(действительно, это - документация, говорит, что это ищет метод с указанным именем и точно теми же типами формального параметра).
Есть ли простой способ найти методы отражающим образом, как getMethod()
делает, но принимающий во внимание полиморфизм, так, чтобы вышеупомянутый отражательный пример мог найти print(Object)
метод при запросах с ("print", String.class)
параметры?
предлагается использовать образец Class.isAssignableFrom ()
для поиска print (String)
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
if (!mname.startsWith("print") {
continue;
}
Type[] pType = m.getGenericParameterTypes();
if ((pType.length != 1)
|| !String.class.isAssignableFrom(pType[0].getClass())) {
continue;
}
}
Самый простой способ сделать это - использовать java.beans.Statement или java.beans.Expression. Делает все эти жесткие дворы за вас.
getMethod () явно не знает, что String может быть передан методу который ожидает объект
«Не подозревая» - это странный способ выразить это. getMethod ()
придерживается своей спецификации. Вы должны указать формальные параметры, а не типы фактических аргументов.