Das einfachste Beispiel, an das ich denken kann, ist:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
aus dem gleichen genommen Collections
. Auf diese Weise Dog
kann a implementieren Comparable<Animal>
und wenn dies Animal
bereits implementiert ist, Dog
muss nichts getan werden.
EDIT für ein echtes Beispiel:
Nach ein paar E-Mail-Ping-Pongs darf ich ein echtes Beispiel von meinem Arbeitsplatz aus präsentieren (yay!).
Wir haben eine Schnittstelle namens Sink
(es spielt keine Rolle, was sie tut), die Idee ist, dass sich Dinge ansammeln . Die Erklärung ist ziemlich trivial (vereinfacht):
interface Sink<T> {
void accumulate(T t);
}
Offensichtlich gibt es eine Hilfsmethode, die a nimmt List
und seine Elemente in a entleert Sink
(es ist etwas komplizierter, aber um es einfach zu machen):
public static <T> void drainToSink(List<T> collection, Sink<T> sink) {
collection.forEach(sink::accumulate);
}
Das ist einfach richtig? Gut...
Ich kann ein haben List<String>
, aber ich möchte es auf ein ablassen Sink<Object>
- das ist eine ziemlich häufige Sache, die wir für uns tun müssen; aber das wird scheitern:
Sink<Object> sink = null;
List<String> strings = List.of("abc");
drainToSink(strings, sink);
Damit dies funktioniert, müssen wir die Erklärung ändern in:
public static <T> void drainToSink(List<T> collection, Sink<? super T> sink) {
....
}