Czytam o metodach ogólnych z OracleDocGenericMethod . Jestem dość zdezorientowany porównaniem, kiedy mówi, kiedy użyć symboli wieloznacznych, a kiedy metod ogólnych. Cytat z dokumentu.
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
Mogliśmy zamiast tego użyć metod ogólnych:
interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! }
[…] To mówi nam, że argument typu jest używany do polimorfizmu; jego jedynym skutkiem jest zezwolenie na użycie różnych rzeczywistych typów argumentów w różnych miejscach wywołań. W takim przypadku należy używać symboli wieloznacznych. Symbole wieloznaczne są przeznaczone do obsługi elastycznych podtypów, co próbujemy tutaj wyrazić.
Czy nie sądzimy, że dzikie karty (Collection<? extends E> c);
są również wspierane przez pewien rodzaj polimorfizmu? Dlaczego więc użycie metody ogólnej nie jest dobre w tym?
Kontynuując, stwierdza:
Metody ogólne pozwalają na użycie parametrów typu do wyrażenia zależności między typami co najmniej jednego argumentu metody i / lub jej zwracanego typu. Jeśli nie ma takiej zależności, nie należy używać metody ogólnej.
Co to znaczy?
Przedstawili przykład
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[…]
Moglibyśmy napisać podpis dla tej metody w inny sposób, bez używania symboli wieloznacznych:
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
Dokument zniechęca do drugiej deklaracji i promuje użycie pierwszej składni? Jaka jest różnica między pierwszą a drugą deklaracją? Wydaje się, że obaj robią to samo?
Czy ktoś może oświetlić ten obszar.
?
w ogóle musisz używać . Mógłbyś przepisać to jako `public static <T1 extends Number, T2 extends Number> void copy (List <T1> dest, List <T2> src) iw tym przypadku stało się oczywiste, co się dzieje.