Comment trouver une méthode surchargée en Java?

En écrivant quelque chose comme

doit(43, 44, "hello"); 

le compilateur sait quelle méthode surchargée doit être appelée. Quand je veux faire la même chose par reflection, je dois découvrir moi-même que la méthode est

 doit(Integer, double, CharSequence...); 

et l’obtenir via quelque chose comme

 Class[] types = {Integer.class, double.class, CharSequence[].class}; declaringClass.getDeclaredMethod("doit", types); 

Je me demande s’il y a déjà quelque chose qui me permet d’écrire juste

 Method m = getMethod(declaringClass, "doit", 43, 44, "hello"); 

Je me demande si quelqu’un l’a déjà fait, car le JLS est un peu compliqué à cet égard.


En fait, il est impossible de se comporter exactement comme le compilateur, car lors de la phase 1, le compilateur accepte uniquement les méthodes qui correspondent, sans boxing ni unboxing. Lorsque getMethod ma getMethod hypothétique getMethod ci-dessus, la distinction entre les primitives et leurs wrappers est déjà perdue (en raison de l’autoboxing lors de la transmission d’arguments via varargs). Ce problème ne semble pas avoir de solution, alors ignorons-le.

Comme suggéré dans une réponse, BeanUtils.invokeMethod se rapproche. Il est censé trouver le meilleur match, peu importe ce que cela signifie. Regarder MethodUtils .getMatchingAccessibleMethod montre que

  • il ne sait rien à propos de varargs
  • c’est non déterministe

alors je cherche quelque chose de mieux.

MethodHandle est un nouveau moyen d’obtenir une méthode surchargée à l’aide d’une signature (java 7):

Exemple:

 static class A { public Ssortingng get() { return "A"; } } static class B extends A { public Ssortingng get() { return "B"; } } public static void main(Ssortingng[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(Ssortingng.class); MethodHandle mh = lookup.findVirtual(A.class, "get", mt);; System.out.println(mh.invoke(new B())); } 

Les sorties:

 B 

Sinon, vous pouvez utiliser Bean Utils de Apache Commons :

 public static Method getAccessibleMethod( Class clazz, Ssortingng methodName, Class[] parameterTypes) 

Selon la documentation :

Renvoie une méthode accessible (c’est-à-dire pouvant être invoquée par reflection) avec un nom et des parameters donnés. Si aucune méthode de ce type ne peut être trouvée, retourne null. Ceci est juste un wrapper pratique pour getAccessibleMethod (Method, méthode).

Paramètres: clazz – Méthode get de cette classe methodName – Méthode get portant ce nom parameterTypes – avec ces types de parameters

L’implémentation obtient la méthode accessible et monte dans la hiérarchie jusqu’à ce qu’elle trouve une correspondance avec celle-ci.

Directement à l’invocation

Afin d’effectuer l’appel directement comme vous l’avez demandé, vous pouvez utiliser cette méthode à partir de la même API:

 public static Object invokeExactMethod( Object object, Ssortingng methodName, Object[] args, Class[] parameterTypes) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 

ou même

 public static Object invokeExactMethod( Object object, Ssortingng methodName, Object[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 

qui localise d’abord la méthode à l’aide de getAccessibleMethod et l’invoque ensuite.