Das dort gezeigte Beispiel (zitiert aus der JLS) lässt es so klingen, als würden Bridge-Methoden nur in Situationen verwendet, in denen rohe Typen verwendet werden. Da dies nicht der Fall ist, möchte ich ein Beispiel anführen, in dem Brückenmethoden für völlig typgerechten generischen Code verwendet werden.
Betrachten Sie die folgende Schnittstelle und Funktion:
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);
}
Wenn Sie diesen Code auf die folgende Weise verwenden, wird eine Brückenmethode verwendet:
Function<String, String> lower = new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
};
applyFunc(lower, "Hello");
Nach dem Löschen wird die Function
Interface enthält die Methode apply(Object)Object
(was Sie durch Dekompilieren des Bytecodes bestätigen können). Natürlich, wenn Sie sich den dekompilierten Code für applyFunc
sehen Sie, dass es einen Aufruf an apply(Object)Object
. Object
ist die obere Grenze seiner Typvariablen, so dass keine andere Signatur sinnvoll wäre.
Wenn also eine anonyme Klasse mit der Methode apply(String)String
implementiert es nicht wirklich die Function
Schnittstelle, es sei denn, es wird eine Brückenmethode erstellt. Die Bridge-Methode erlaubt es allen generisch typisierten Code, diese Schnittstelle zu nutzen Function
Umsetzung.
Interessanterweise nur, wenn die Klasse einige andere Schnittstelle mit der Signatur apply(String)String
und nur wenn die Methode über eine Referenz dieses Schnittstellentyps aufgerufen wird, würde der Compiler einen Aufruf mit dieser Signatur ausgeben.
Auch wenn ich den folgenden Code habe:
Function<String, String> lower = ...;
lower.apply("Hello");
Der Compiler gibt weiterhin einen Aufruf an apply(Object)Object
.
Es gibt tatsächlich noch eine andere Möglichkeit, den Compiler dazu zu bringen, Folgendes aufzurufen apply(String)String
Sie macht sich jedoch den magischen Typ zunutze, der einem anonymen Klassenerstellungsausdruck zugewiesen ist, der sonst nicht aufgeschrieben werden kann:
new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
}.apply("Hello");