2017-06-29 1 views
1

Je rencontre une exception NoSuchMethodException lorsque j'essaie d'appeler getMethod sur une méthode de la même classe sans arguments provenant d'un nom de chaîne extrait d'un hashmap. Un conseil, ou un autre moyen d'appeler une méthode dans la même classe avec seulement un nom String de la méthode? L'appel pour obtenir la méthode est ici:Réflexion Java NoSuchMethodException lors du référencement d'une méthode dans la même classe

if (testChoices.containsKey(K)) { 
     String method = testChoices.get(K); 
     System.out.println(method); 

     try { 
      java.lang.reflect.Method m = TST.getClass().getMethod(method); 
      m.invoke(testChoices.getClass()); 
     } catch (NoSuchMethodException e1) { 
      // TODO Auto-generated catch block 
      System.out.println("No method found"); 
      e1.printStackTrace(); 
     } catch (SecurityException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 


     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 

L'une des méthodes que je suis en train d'appeler est ici:

private static void testgetDomainLic() throws IOException { 

Et l'entrée de carte étant appelée est ici:

testChoices.put(1, "testgetDomainLic"); 
+0

La méthode statique 'testgetDomainLic()' est-elle définie dans la classe TST ou dans une superinterface? –

+0

TST est juste une instance de la classe où testgetDomainLic() est. – user8232299

+0

Je l'ai changé pour appeler la classe directement définie avec Class.forName et il ne trouve toujours pas la méthode. – user8232299

Répondre

0

Je pense que dans votre cas, vous pouvez simplement changer getMethod à getDeclaredMethod. getMethod renvoie uniquement les méthodes publiques.

Le hiccup ici est qu'ils ont en réalité différentes sémantiques autres que si elles retournent ou non des méthodes non publiques. getDeclaredMethod inclut uniquement les méthodes déclarées et non héritées.

Ainsi, par exemple:

class Foo { protected void m() {} } 
class Bar extends Foo {} 
Foo actuallyBar = new Bar(); 
// This will throw NoSuchMethodException 
// because m() is declared by Foo, not Bar: 
actuallyBar.getClass().getDeclaredMethod("m"); 

Dans le pire des cas comme celui-ci, vous devez boucle à travers toutes les méthodes déclarées, comme ceci:

Class<?> c = obj.getClass(); 
do { 
    for (Method m : c.getDeclaredMethods()) 
     if (isAMatch(m)) 
      return m; 
} while ((c = c.getSuperclass()) != null); 

ou comptable des interfaces (surtout parce qu'ils peuvent déclarer les méthodes statiques maintenant):

List<Class<?>> classes = new ArrayList<>(); 
for (Class<?> c = obj.getClass(); c != null; c = c.getSuperclass()) 
    classes.add(c); 
Collections.addAll(classes, obj.getClass().getInterfaces()); 
Method m = classes.stream() 
        .map(Class::getDeclaredMethods) 
        .flatMap(Arrays::stream) 
        .filter(this::isAMatch) 
        .findFirst() 
        .orElse(null); 

Et en note de côté, vous avez probablement ne pas besoin d'appeler m.setAccessible(true), parce que vous invoquez à partir de la classe qui le déclare. Ceci est cependant nécessaire dans d'autres contextes.

+0

Cela a fonctionné pour moi, merci beaucoup – user8232299

0

Je ne suis pas un expert, mais essayez de changer votre méthode pour qu'elle ne soit pas privée.

Des méthodes privées peuvent être appelées par réflexion, mais il existe des étapes supplémentaires. Voir Any way to Invoke a private method?

+1

L'OP reçoit une exception NoSuchMethodException. Le problème est avec 'getMethod()' - pas avec 'invoke()'. –

+0

En outre, j'ai essayé de supprimer le privé, mais il donne toujours la même erreur – user8232299

+0

OK. Donc, je suis en train de régler le problème qu'ils n'ont pas encore eu! –