Java:当方法明确存在时NoSuchMethodException

Bri*_*n S 41 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;
}
Run Code Online (Sandbox Code Playgroud)

当我构造Callback对象时,我使用这样的语法:

new Callback(this, "myMethod", boolean.class)
Run Code Online (Sandbox Code Playgroud)

当我尝试创建我的伪回调时,它会命中NoSuchMethodExceptioncatch块.我在上面包含了一些跟踪调试,以显示我的一个方法的输出失败.输出:

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)
Run Code Online (Sandbox Code Playgroud)

我无法解决问题,所以我开始打猎,但收效甚微.我能找到的最好的是提到编译的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似乎没有问题找到它.救命?:(

ZZ *_*der 106

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

你需要使用getDeclaredMethod().

  • 3年后......在我的案例中,这很有意义.虽然我开始在http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod(java.lang.String,java.lang)上阅读这两种方法的文档.班级......)他们没有提到这些信息.也许你查看了代码?对你有益.+1 (3认同)
  • 这对我有帮助,但相反。我尝试使用 getDeclaredMethod() 调用一个公共方法,但没有找到它。切换到 getMethod() 并且它可以工作 (2认同)

Tho*_*sen 6

您需要参数列表对于您希望调用成功的方法是绝对正确的。

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

  • 这就是我的案例中的问题。我没有为我想要获取的方法提供参数类型。我的代码之前看起来像`Method method = SearchApiController.class.getMethod("searchPost")`,但我的方法采用了一堆我在通过反射获取时错过指定的参数。我的代码工作起来就像一个魅力。`Method method = SearchApiController.class.getMethod("searchPost", String.class, SearchQuery.class, String.class, String.class, String.class);` (2认同)

Ada*_*ume 5

getMethod的Javadoc 并不明确,但是看起来它可能会为非公共方法抛出NoSuchMethodException,而您的方法是私有的。

  • 是的,就是这样。您的建议使我遍历了Class的源代码。`getMethod`调用(私有)`getMethod0`。“ getMethod0”调用“ privateGetDeclaredMethods(true)”,其中“ true”是“ publicOnly”。 (2认同)