我能想到的最简单的例子是:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
取自相同Collections
。这样,一个Dog
就可以实现Comparable<Animal>
,如果Animal
已经实现,Dog
则无需执行任何操作。
编辑一个真实的例子:
经过一些电子邮件乒乓球后,我可以在我的工作场所中展示一个真实的例子(是的!)。
我们有一个称为的接口Sink
(它做什么无关紧要),其思想是累积事物。该声明非常简单(简化):
interface Sink<T> {
void accumulate(T t);
}
显然,有一个辅助方法需要aList
并将其元素排到a Sink
(这有点复杂,但为了简单起见):
public static <T> void drainToSink(List<T> collection, Sink<T> sink) {
collection.forEach(sink::accumulate);
}
这很简单吧?好...
我可以有一个List<String>
,但我想将其消耗掉Sink<Object>
-对我们来说这是很常见的事情;但这将失败:
Sink<Object> sink = null;
List<String> strings = List.of("abc");
drainToSink(strings, sink);
为此,我们需要将声明更改为:
public static <T> void drainToSink(List<T> collection, Sink<? super T> sink) {
....
}