Java:当方法明确存在时NoSuchMethodException

时间:2010-07-08 02:24:14

标签: java reflection

在我目前的项目中,我觉得有必要使用反射在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 个答案:

答案 0 :(得分:97)

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

您需要使用getDeclaredMethod()

答案 1 :(得分:5)

getMethod的Javadoc不是显式的,但看起来它可能会为非公开的方法抛出NoSuchMethodException,并且您的方法是私有的。

答案 2 :(得分:2)

您需要参数列表对于呼叫成功所需的方法绝对正确。

我发现在进行反射时,微小的步骤很重要,因为编译器没有帮助。编写一个小片段,实际上在特定情况下实际调用您想要的方法,然后当它起作用时,将其概括为此处的框架。我会专注于传递的参数。

答案 3 :(得分:0)

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

因为您使用反射,所以问题可能与版本控制无关。当然,这不会解释getMethodgetDeclaredMethods之间的不同行为,因为您是针对同一个Class实例运行它们,因此版本差异实际上是不可能的。

您确定这些参数符合您的实际方法吗?