Invocation de méthode surchargée : prioriser les types de paramètres réels
Le mécanisme de surcharge de méthode de Java sélectionne l'implémentation la plus appropriée en fonction des types de paramètres déclarés. Cependant, une idée fausse courante est qu'il prend également en compte les types réels lors de la résolution de la surcharge.
Le défi
Considérez l'extrait de code suivant :
interface Callee { public void foo(Object o); public void foo(String s); public void foo(Integer i); } class CalleeImpl implements Callee { public void foo(Object o) { logger.debug("foo(Object o)"); } public void foo(String s) { logger.debug("foo(\"" + s + "\")"); } public void foo(Integer i) { logger.debug("foo(" + i + ")"); } } Callee callee = new CalleeImpl(); Object i = new Integer(12); Object s = "foobar"; Object o = new Object(); callee.foo(i); callee.foo(s); callee.foo(o);
Lors de l'exécution, ce code imprime de manière inattendue "foo(Object o)" trois fois, plutôt que de sélectionner différentes implémentations en fonction du paramètre réel types.
La cause profonde
En Java, l'invocation de méthode est distribuée dynamiquement pour l'objet sur lequel la méthode est appelée, mais pas pour les types de paramètres. La spécification du langage Java indique explicitement que les « types d'arguments au moment de la compilation » déterminent la signature de la méthode sélectionnée.
Par conséquent, les déclarations de paramètres remplacent toute conversion de type ou promotion potentielle qui se produit lors de l'affectation des paramètres. Par conséquent, les trois appels dans le code fourni sont résolus en la méthode "foo(Object o)" puisque Object est le type déclaré des trois paramètres.
Résolution
Pour résoudre ce problème et hiérarchiser les types de paramètres réels dans la résolution de surcharge, envisagez les stratégies suivantes :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!