Das Beispiel gibt (von der JLS zitiert) macht es klingt gezeigt wie Bridge-Methoden werden nur in Situationen verwendet, in denen Rohtypen verwendet werden.Da dies nicht der Fall ist, dachte ich, ich würde ein Beispiel heranziehen, in dem Bridge-Methoden für vollständig typengleichen 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 in der folgenden Art und Weise verwendet werden, eine Brücke Methode verwendet wird:
Function<String, String> lower = new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
};
applyFunc(lower, "Hello");
Nach dem Löschen der Function
Schnittstelle enthält die Methode apply(Object)Object
(was Sie durch Dekompilieren des Bytecodes bestätigen können). Wenn Sie sich den dekompilierten Code für applyFunc
ansehen, sehen Sie natürlich, dass er einen Aufruf an apply(Object)Object
enthält. Object
ist die Obergrenze seiner Typvariablen, daher ist keine andere Signatur sinnvoll. Wenn eine anonyme Klasse mit der Methode apply(String)String
erstellt wird, implementiert sie die Schnittstelle Function
nicht, wenn keine Bridge-Methode erstellt wird Die Bridge-Methode ermöglicht allen generisch typisierten Code, diese Function
Implementierung zu verwenden.
Interessanterweise nur, wenn die Klasse einige andere Schnittstelle mit der Unterschrift apply(String)String
und nur dann durchgeführt, wenn das Verfahren über eine Referenz dieser Schnittstelle Typ hieß würde der Compiler jemals einen Anruf mit dieser Signatur emittieren.
Auch wenn ich den folgenden Code haben:
Function<String, String> lower = ...;
lower.apply("Hello");
Der Compiler noch einen Aufruf an apply(Object)Object
emittiert.
Es ist eigentlich eine andere Art und Weise, den Compiler zu erhalten apply(String)String
zu nennen, aber es nutzt die magische Art zu einer anonymen Klasse Schöpfung Ausdruck zugeordnet, die gelegt werden kann nicht anders geschrieben:
new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
}.apply("Hello");
Auch ohne Generika sind Bridge-Methoden für kovariante Rückgabetypen notwendig. –
BridgeMethodResolver Link ist kaputt :( – BrunoJCM
@BrunoJCM good catch. Ich habe den Link wiederhergestellt (die Klasse wurde aus dem Projekt 'org.springframework.core' in das Projekt' spring-framework' verschoben: https://fisheye.springsource.org /browse/spring-framework/org.springframework.core/src/main/java/org/springframework/core/BridgeMethodResolver.java#rdc41daa3db350ef9a4b14ef1d750d79cb22cf431) – VonC