Ich lese über generische Methoden von OracleDocGenericMethod . Ich bin ziemlich verwirrt über den Vergleich, wenn es darum geht, wann Platzhalter und wann generische Methoden verwendet werden sollen. Zitieren aus dem Dokument.
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
Wir hätten hier stattdessen generische Methoden verwenden können:
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! }
[…] Dies sagt uns, dass das Typargument für den Polymorphismus verwendet wird; Die einzige Auswirkung besteht darin, dass verschiedene tatsächliche Argumenttypen an verschiedenen Aufrufstandorten verwendet werden können. In diesem Fall sollten Platzhalter verwendet werden. Platzhalter unterstützen die flexible Untertypisierung, die wir hier ausdrücken möchten.
Denken wir nicht, dass Wildcards wie (Collection<? extends E> c);
auch Polymorphismus unterstützen? Warum wird die Verwendung generischer Methoden dann als nicht gut angesehen?
Weiter geht es, heißt es,
Mit generischen Methoden können Typparameter verwendet werden, um Abhängigkeiten zwischen den Typen eines oder mehrerer Argumente für eine Methode und / oder ihren Rückgabetyp auszudrücken. Wenn es keine solche Abhängigkeit gibt, sollte keine generische Methode verwendet werden.
Was bedeutet das?
Sie haben das Beispiel vorgestellt
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[…]
Wir hätten die Signatur für diese Methode auch anders schreiben können, ohne Platzhalter zu verwenden:
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
Das Dokument entmutigt die zweite Deklaration und fördert die Verwendung der ersten Syntax? Was ist der Unterschied zwischen der ersten und der zweiten Erklärung? Beide scheinen dasselbe zu tun?
Kann jemand Licht in diesen Bereich bringen.
?
überhaupt verwenden müssen. Sie können es als `public static <T1 erweitert Number, T2 erweitert Number> void copy (List <T1> dest, List <T2> src) umschreiben und in diesem Fall wird klar, was los ist.