2013-06-21 6 views
1

У меня возникли проблемы с использованием отражения на Java. Я пытаюсь сохранить метод структуры данных, но получаю сообщение об ошибке. ОшибкаJava, отражение, получение метода из класса

java.lang.NoSuchMethodException: cs671.eval.SerialList.add(java.lang.Integer, java.lang.String)

метод, в данном случае, что я пытаюсь получить метод дополнения для SerialList, который принимает сравнимый и объект в качестве его параметров.

structType = "cs671.eval.SerialList", keyType = "java.lang.Integer" и valType = "java.lang.String" - это строки, которые были прочитаны из файла.

Class dataClass = null, comparableClass = null, objectClass = null; 

try{ // create data structure 
    dataClass = Class.forName(structType); 
    comparableClass = Class.forName(keyType); 
    objectClass = Class.forName(valType); 
} 
catch(ClassNotFoundException e){} 

java.lang.Object structObj = null; 

try{ // Create a data structure object 
    structObj = dataClass.newInstance(); 
} 
catch(Exception e){} 
Method m = null; 
try{ // Attempt to get add method for the data structure 
    m = dataClass.getMethod("add", comparableClass, objectClass); // This is where it fails 
} 
catch(Exception e){} 

В основном я пытаюсь получить правильный метод на праве структуры данных с правильными классами, которые собираются получить прошел в этот метод, но я не знаю, как сказать, метод getMethod, что эти классы (compareClass и objectClass) являются правильными.

Заранее благодарен!

Добавлено: Вот способ добавить подпись SerialList в public void add(java.lang.Comparable, java.lang.Object)

+0

Что такое подпись 'cs671.eval.SerialList.add'? – Polygnome

+0

Вы пробовали запустить Class.getMethods и распечатать списки типов имен/параметров? Если, например, SerialList расширяет ArrayList , тогда метод Add фактически будет добавлять (int, Object). – Sbodd

+0

@Polygnome: добавляет подпись к сообщению. –

ответ

5

Вы говорите -

Метод, в этом случае, что я пытаюсь получить метод дополнения для SerialList, что принимает Сопоставимый и Объект в качестве параметров.

Передача классов - java.lang.Integer, java.lang.String.


Только примечание - только открытые методы могут видеть getMethod() для не-публики вы должны использовать getDeclaredMethod() вместо этого.

+0

Эти классы, Integer и String, являются классами объектов, которые позже будут переданы методу добавления в коде. Я получил их, прочитав имя класса, создав им экземпляр класса и передав эти экземпляры классов в getMethod. Однако getMethod ожидает сравнения и объекта. Мне нужно знать, как использовать эти два класса, чтобы сообщить getMethod, что они верны, потому что Integer будет сопоставимым объектом, а String будет объектом Object. –

+0

'Comparable.class' и' Object.class'. –

+0

Я не хочу, чтобы жестко закодировать их, потому что позже на линии другой метод может быть получен с другой подписью. –

1

От http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29:

Чтобы найти соответствующий метод в классе C: Если C объявляет ровно один публичный метод с указанным именем и точно такие же формальные типы параметров, что метод отражается. Если в C найдено более одного такого метода, и один из этих методов имеет тип возврата, который более специфичен, чем любой другой, этот метод отражается; в противном случае один из методов выбирается произвольно.

=> Вам необходимо пройти java.lang.Comparable.class & java.lang.Object.class

0

Извинения за предоставление неправильный ответ ранее. На основании ваших комментариев кажется, что вы пытаетесь получить метод, избегая предоставления определенных типов параметров, необходимых для подписи этого метода.

Если мое понимание верное, вы должны использовать Class#getMethods() и изучить полученный метод Method[] для вашего метода.Рассмотрим код скелета, как это:

Method[] methods = dataClass.getMethods(); 
boolean matched = false; 
// find a matching method by name 
for (Method method: methods) { 
    Class<?>[] parameterTypes = method.getParameterTypes(); 
    if ("add".equals(method.getName()) && parameterTypes.length == 2) { 
     // method is your target method 
     // however you'll need more strict checks if there can be another add method 
     // in your class with 2 different parameter types 
    } 
} 
0

Как и другие ответы заявили, использовать getMethod() вам нужно знать и использовать фактические объявленные формальные параметры метода, которые вы пытаетесь получить.

Однако, если по какой-либо причине вы не знаете формальные параметры во время компиляции, вы можете перебирать все методы из класса, пока не найдете метод, который соответствует вашим параметрам (или найдите наиболее специфический метод, который соответствует вашим параметрам).

Существует функциональность, написанная для этого уже в apache commons bean utils, в частности в org.apache.commons.beanutils.MethodUtils.invokeMethod(...) и MethodUtils.getMatchingAccessibleMethod(...).

Исходный код для вышеуказанных методов можно легко просмотреть онлайн here.

Смежные вопросы