L'exemple montré là (cité de la JLS) fait sonner comme Les méthodes de pont ne sont utilisées que dans les situations où des types bruts sont utilisés.Puisque ce n'est pas le cas, j'ai pensé que je ferais pipi avec un exemple où les méthodes de pont sont utilisées pour le code générique totalement correct.
Tenir compte de l'interface et la fonction suivante:
public static interface Function<A,R> {
public R apply (A arg);
}
public static <A, R> R applyFunc (Function<A,R> func, A arg) {
return func.apply(arg);
}
Si vous utilisez ce code de la manière suivante, une méthode de pont est utilisé:
Function<String, String> lower = new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
};
applyFunc(lower, "Hello");
Après l'effacement, l'interface Function
contient la méthode apply(Object)Object
(que vous pouvez confirmer en décompilant le bytecode). Naturellement, si vous regardez le code décompilé pour applyFunc
, vous verrez qu'il contient un appel à apply(Object)Object
. Object
est la limite supérieure de ses variables de type, donc aucune autre signature n'aurait de sens. Par conséquent, lorsqu'une classe anonyme est créée avec la méthode apply(String)String
, elle n'implémente pas réellement l'interface Function
à moins qu'une méthode de pontage ne soit créée. La méthode de pont permet à tout le code typé générique d'utiliser cette implémentation Function
.
Fait intéressant, que si la classe a mis en œuvre une autre interface avec la signature apply(String)String
et seulement si la méthode a été appelée par une référence de ce type d'interface serait le compilateur jamais émettre un appel avec cette signature.
Même si j'ai le code suivant:
Function<String, String> lower = ...;
lower.apply("Hello");
Le compilateur émet toujours un appel à apply(Object)Object
.
Il est en fait une autre façon d'obtenir le compilateur d'appeler apply(String)String
, mais il profite du type magique attribué à une expression de création de classe anonyme qui ne peut autrement écrit:
new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
}.apply("Hello");
Même sans génériques, les méthodes de pont sont nécessaires pour les types de retour covariant. –
Le lien BridgeMethodResolver est cassé :( – BrunoJCM
@BrunoJCM bonne capture J'ai restauré le lien (la classe a été déplacée du projet 'org.springframework.core' au projet' spring-framework': https://fisheye.springsource.org /browse/spring-framework/org.springframework.core/src/main/java/org/springframework/core/BridgeMethodResolver.java#rdc41daa3db350ef9a4b14ef1d750d79cb22cf431) – VonC