Java:NoSuchMethodException当方法明显存在时

Java:NoSuchMethodException当方法明显存在时,java,reflection,Java,Reflection,在我当前的项目中,我觉得有必要使用反射在Java中创建一种模拟回调系统。然而,我在让我的反射真正发挥作用方面遇到了问题。故障代码如下所示: public Callback(Object parentObj, String methodName, Class<?>...parameters) { if(parentObj == null) throw new IllegalArgumentException("parentObj cannot be null",

在我当前的项目中,我觉得有必要使用反射在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;
}
当我尝试创建伪回调时,它会点击
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)
private void my.package.MyClass.myMethod(布尔值)
java.lang.NoSuchMethodException:my.package.MyClass.myMethod(布尔值)
位于java.lang.Class.getMethod(Class.java:1605)
在my.package.other.Callback.(Callback.java:63)
我无法解决这个问题,所以我开始打猎,但收效甚微。我能找到的最好的方法就是提到编译后的JAR和运行时之间的版本控制冲突。但是,
MyJar.jar/META-INF/MANIFEST.MF
包含由以下人员创建的
:1.6.0_02(Sun Microsystems Inc.)
。我的IDE正在运行
C:\ProgramFiles\Java\jdk1.6.0\u 02\bin\javac.exe
来编译我的项目。我正在使用
C:\ProgramFiles\Java\jdk1.6.0\u 02\bin\Java.exe
运行我的JAR


我不知道为什么
Class.getMethod
声称该方法不存在,但是
Class.getMethods
似乎在查找它时没有问题。帮助?:(

可能导致NoSuchMethodException的版本控制问题不是编译器版本之间的差异。这是编译时与运行时的MyClass版本(在您的情况下)的差异

但是,由于您使用的是反射,您发出的问题可能与版本控制无关。当然,这不会解释
getMethod
getDeclaredMethods
之间的不同行为,因为您在同一类实例上运行它们,因此版本差异实际上是不可能的


您确定参数与您的实际方法匹配吗?

的Javadoc不是显式的,但它看起来可能会对非公共的方法抛出NoSuchMethodException,而您的方法是私有的。

您需要参数列表绝对正确,才能使调用成功


我发现,在进行反射时,小步骤很重要,因为编译器没有帮助。编写一个小片段,在这个特定的情况下,它实际上调用了您想要的方法,然后当它起作用时,在这里将其推广到框架中。我将重点关注传递的参数。

您的方法是私有的,但
getMethod()
仅返回公共方法


你需要使用
getDeclaredMethod()

,这就是为什么你不依赖反射,反射充其量是不可靠的。我不会说它不可靠,但它可能很复杂,效率也很低。它的可靠性肯定比你的编译器能证明正确的东西要低。-)是的,就是这样。你的建议让我在课堂上仔细阅读了源代码
getMethod
调用(私有)
getMethod0
getMethod0
调用
privateGetDeclaredMethods(true)
,其中
true
是“
publicOnly
”是!这在不强迫我使用公共方法的情况下解决了问题。谢谢3年后。。。这对我来说很有意义。虽然我开始阅读这两种方法的文档(java.lang.Class…),但它们没有提到这些信息。也许你查过密码了?对你有好处+我的头连续两个小时撞在墙上。谢谢你,伙计!很棒的命名约定java。。。getPrivateMethod.怎么样。。老天爷,这帮了我的忙,但恰恰相反。我试图用getDeclaredMethod()调用一个公共方法,但它没有找到。切换到getMethod(),它可以工作这就是我的问题所在。我没有为我想要得到的方法提供参数类型。我以前的代码看起来像
Method=SearchApiController.class.getMethod(“searchPost”)
,但我的方法在通过反射获取它的过程中忽略了一系列指定的参数。我的代码工作起来很有魅力<代码>方法方法=SearchApicController.class.getMethod(“searchPost”,String.class,SearchQuery.class,String.class,String.class,String.class)
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)