Java: nosuchmethodexception lorsque la méthode existe clairement

Sur mon projet actuel, j'ai ressenti le besoin de créer une sorte de système de rappel simulé en Java en utilisant la réflexion. Cependant, j'ai des problèmes pour que ma réflexion fonctionne réellement. Le code en faute suit:

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;
}

Quand je construis l'objet Callback, j'utilise la syntaxe comme ceci:

new Callback(this, "myMethod", boolean.class)

Lorsque j'essaie de créer mon pseudo rappel, il frappe le NoSuchMethodException bloc catch. J'ai inclus un débogage de trace ci-dessus pour montrer la sortie de l'une de mes méthodes échouant. Le sortie:

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)

Je n'arrivais pas à comprendre le problème, alors j'ai commencé à chasser, en vain. Le mieux que j'ai pu trouver était la mention du conflit de version entre le JAR compilé et le runtime. Cependant, MyJar.jar/META-INF/MANIFEST.MF contient Created-By: 1.6.0_02 (Sun Microsystems Inc.). Mon IDE est en cours d'exécution C:Program FilesJavajdk1.6.0_02binjavac.exe pour compiler mon projet. J'utilise C:Program FilesJavajdk1.6.0_02binjava.exe pour exécuter mon pot.

Je ne comprends pas pourquoi Class.getMethod prétend que la méthode n'existe pas, mais Class.getMethods semble ne pas avoir de problème à la trouver. De l'aide? :(

29
demandé sur Brian S 2010-07-08 06:24:13

4 réponses

Votre méthode est privée mais getMethod() ne renvoie que la méthode publique.

Vous devez utiliser getDeclaredMethod().

90
répondu ZZ Coder 2012-09-12 00:21:25

Le Javadoc pour getMethod n'est pas explicite, mais il semble qu'il puisse lancer une exception NoSuchMethodException pour les méthodes qui ne sont pas publiques, et votre méthode est privée.

4
répondu Adam Crume 2010-07-08 02:36:16

Vous avez besoin que la liste des paramètres soit absolument correcte pour la méthode que vous voulez pour que l'appel réussisse.

J'ai trouvé que de petites étapes sont importantes lors de la réflexion car le compilateur n'aide pas. Écrivez un petit extrait qui appelle exactement la méthode que vous voulez dans ce cas particulier, puis quand cela fonctionne, généralisez-le dans le framework ici. Je me concentrerais sur les paramètres passés.

1
répondu Thorbjørn Ravn Andersen 2010-07-08 02:42:53

Le problème de versioning qui peut causer NoSuchMethodException n'est pas une différence entre les versions du compilateur. C'est une différence dans la version de (dans votre cas) MyClass au moment de la compilation par rapport à l'exécution.

Puisque vous utilisez la réflexion, vous n'avez peut-être rien à voir avec le versionnage. Certes, cela n'expliquerait pas un comportement différent entre getMethod et getDeclaredMethods, parce que vous les exécutez sur la même instance de classe, donc une différence de version n'est pas vraiment possible.

Êtes-vous sûr que les paramètres correspondent à votre méthode réelle?

0
répondu Laurence Gonsalves 2010-07-08 02:35:44