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
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.
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.