Подтвердить что ты не робот

Java: исключение NoSuchMethodException, когда метод явно существует

В моем текущем проекте я почувствовал необходимость создания своего рода симулированной системы обратного вызова в 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)

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

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, похоже, не имеет проблем с его поиском. Помогите?: (

4b9b3361

Ответ 1

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

Вам нужно использовать getDeclaredMethod().

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

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

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