Przykład pokazany tam (cyt JLS) sprawia, że dźwięk jak Metody mostów są używane tylko w sytuacjach, w których używane są typy surowe.Ponieważ tak nie jest, pomyślałem, że wpadnę na przykład, gdzie metody mostowe są używane do generycznego kodu całkowicie poprawnego typowo.
Rozważmy następujący interfejs oraz funkcję:
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);
}
Jeśli użyjesz tego kodu w następujący sposób, używany jest metoda most:
Function<String, String> lower = new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
};
applyFunc(lower, "Hello");
Po skasowaniem, interfejs Function
zawiera metodę apply(Object)Object
(którą można potwierdzić przez dekompilację kodu bajtowego). Naturalnie, jeśli spojrzysz na dekompilowany kod dla applyFunc
, zobaczysz, że zawiera on połączenie z apply(Object)Object
. Object
to górna granica jego zmiennych typu, więc żadna inna sygnatura nie miałaby sensu.
Tak więc, gdy klasa anonimowa jest tworzona za pomocą metody apply(String)String
, nie implementuje ona interfejsu Function
, chyba że zostanie utworzona metoda mostu. Metoda bridge pozwala wszystkim ogólnie wpisanym kodom korzystać z tej implementacji Function
.
Co ciekawe, tylko jeśli klasa wdrożone pewne inne interfejs z podpisem apply(String)String
i tylko wtedy, gdy metoda nazwano poprzez odniesienie tego typu interfejsu będzie kompilator zawsze emitują połączenia z tym podpisem.
Nawet jeśli mam następujący kod:
Function<String, String> lower = ...;
lower.apply("Hello");
Kompilator nadal emituje wywołanie apply(Object)Object
.
Jest rzeczywiście jeden sposób, aby uzyskać kompilatora, aby zadzwonić apply(String)String
, ale korzysta z magicznym typu przypisanego do anonimowej wypowiedzi tworzenia klasy, która nie może inaczej być zapisane:
new Function<String, String>() {
public String apply (String arg) {
return arg.toLowerCase();
}
}.apply("Hello");
Nawet bez generycznych metod mostkowania są konieczne do kowariantnych typów zwracania. –
Link BridgeMethodResolver jest zepsuty :( – BrunoJCM
@BrunoJCM dobry haczyk Mam przywrócić link (klasa została przeniesiona z projektu 'org.springframework.core' do projektu' spring-framework': https://fisheye.springsource.org /browse/spring-framework/org.springframework.core/src/main/java/org/springframework/core/BridgeMethodResolver.java#rdc41daa3db350ef9a4b14ef1d750d79cb22cf431) – VonC