3

以下三个签名有什么区别?

static <T> void foo(List<T>,           Comparator<? super T>);
static <T> void bar(List<? extends T>, Comparator<T>        );
static <T> void baz(List<? extends T>, Comparator<? super T>);

我知道泛型中的含义extendssuper含义。foo我的问题是,bar和之间是否有区别baz。我应该使其中一个参数不变,而另一个参数在适当的方向上变体,还是应该使它们都变体?这有什么不同吗?

4

3 回答 3

5

PECS - 生产者延伸,消费者超级。

解释这个“规则”:

  • extends表示泛化对象产生该类型的元素。当它是一个集合时,这意味着您只能从集合中获取元素,而不能将它们放入。比较器
  • super表示对象使用选定类型的对象。因此,您可以添加到集合中,但不能从中读取。
  • 缺少 extends 和 super 意味着您可以为指定的确切类型执行这两种操作。

关于Comparator,我认为这没有任何区别。通常,这是<? super T>因为您的比较器消耗了对象,但在所有三种情况下,您都可以安全地调用Collections.sort(list, comparator);(其签名是<? super T>

于 2012-03-17T22:42:24.787 回答
2

唯一的区别是是否表示、或介于两者之间T的类型参数。ListComparator

就调用者而言,这三个方法签名是等价的,即只要其中一个可以使用,其他的也可以使用。

因为方法实现foo可能是最方便的,因为它允许修改列表而不需要额外的捕获转换,这需要委托给辅助方法。

于 2012-03-18T00:15:40.773 回答
1

我相信这? extends T意味着 theList可能是从 T 派生的任何类型的泛型,而List<T>只能是ListofT而不是它的任何派生类。

于 2012-03-17T22:43:00.903 回答