На моем текущем проекте я чувствовал потребность создать своего рода моделируемую систему обратного вызова в 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
блок выгоды. Я включал некоторую отладку трассировки выше для проявления вывода одного из моего сбоя методов. Вывод:
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
кажется, не имеет никакой проблемы при нахождении его.Помощь?:(
Ваш метод является приватным, но getMethod()
возвращает только публичный метод.
Вам нужно использовать getDeclaredMethod()
.
Документация Javadoc для getMethod не является явной, но похоже, что она может вызвать исключение NoSuchMethodException для методов, которые не являются общедоступными, а ваш метод является частным.
Проблема управления версиями, которая может вызвать исключение NoSuchMethodException, не является разницей между версиями компилятора. Это разница в версии (в вашем случае) MyClass
во время компиляции и во время выполнения.
Поскольку вы используете отражение, проблема может не иметь ничего общего с управлением версиями. Конечно, это не объясняет различное поведение между getMethod
и getDeclaredMethods
, потому что вы запускаете их для одного и того же экземпляра класса, поэтому разница в версиях на самом деле невозможна.
Вы уверены, что параметры соответствуют вашему фактическому методу?
Вам нужно, чтобы список параметров был абсолютно верным для метода, который вы хотите вызвать, чтобы он был успешным.
Я обнаружил, что при рефлексии важны крошечные шаги, потому что компилятор не помогает. Напишите небольшой фрагмент, который фактически вызывает именно тот метод, который вы хотите использовать в этом частном случае, а затем, когда это сработает, обобщите его в рамках здесь. Я бы остановился на переданных параметрах.