Java: NoSuchMethodException, когда метод явно существует - PullRequest
36 голосов
/ 08 июля 2010

В моем текущем проекте я чувствовал необходимость создать своего рода симулированную систему обратного вызова в Java с использованием рефлексии.Тем не менее, у меня возникают проблемы с тем, чтобы мое отражение действительно функционировало.Код ошибки:

public Callback(Object parentObj, String methodName, Class<?>...parameters)
{
    if(parentObj == null)
        throw new IllegalArgumentException("parentObj cannot be null", new NullPointerException());

    Class<?> clazz = parentObj.getClass();

    // Trace debugging, see output
    for(Method m : clazz.getDeclaredMethods())
        if(m.getName().equals("myMethod")) System.out.println (m);

    try { this.method = clazz.getMethod(methodName, parameters); }
    catch(NoSuchMethodException nsme) { nsme.printStackTrace(); } // Exception caught
    catch(SecurityException se) { se.printStackTrace(); }

    this.parentObj = parentObj;
    this.parameters = parameters;
}

Когда я создаю объект Callback, я использую синтаксис, подобный этому:

new Callback(this, "myMethod", boolean.class)

Когда я пытаюсь создать свой псевдозвонок, он попадает в блок NoSuchMethodException catch.Я включил некоторую отладку трассировки выше, чтобы показать, что вывод одного из моих методов завершился ошибкой.Вывод:

private void my.package.MyClass.myMethod(boolean)
java.lang.NoSuchMethodException: my.package.MyClass.myMethod(boolean)
    at java.lang.Class.getMethod(Class.java:1605)
    at my.package.other.Callback.<init>(Callback.java:63)

Я не мог разобраться в проблеме, поэтому я начал охоту, но безрезультатно.Лучшее, что я смог найти, было упоминание о конфликте версий между скомпилированным JAR и средой выполнения.Однако MyJar.jar/META-INF/MANIFEST.MF содержит Created-By: 1.6.0_02 (Sun Microsystems Inc.).Моя IDE работает C:\Program Files\Java\jdk1.6.0_02\bin\javac.exe для компиляции моего проекта.Я использую C:\Program Files\Java\jdk1.6.0_02\bin\java.exe для запуска JAR.

Я в растерянности, почему Class.getMethod утверждает, что метод не существует, но, похоже, у Class.getMethods нет проблем с его поиском.Помогите?(

Ответы [ 4 ]

101 голосов
/ 08 июля 2010

Ваш метод закрыт, но getMethod() возвращает только открытый метод.

Вам необходимо использовать getDeclaredMethod().

5 голосов
/ 08 июля 2010

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

2 голосов
/ 08 июля 2010

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

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

0 голосов
/ 08 июля 2010

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

Поскольку вы используете рефлексию, проблема может не иметь ничего общего с управлением версиями. Конечно, это не объясняло бы различное поведение между getMethod и getDeclaredMethods, потому что вы запускаете их для одного и того же экземпляра класса, следовательно, разница в версии на самом деле невозможна.

Вы уверены, что параметры соответствуют вашему фактическому методу?

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