Java中通用签名的区别

时间:2012-10-17 09:58:15

标签: java generics

我们在教程中使用以下signture(作为界面的一部分)

<T> List<Comparable<T>> sort(Collection<Comparable<T>> c, boolean ascending);

我们发现在没有警告的情况下实施该方法几乎是不可能的:

public <T> List<Comparable<T>> sort(Collection<Comparable<T>> c, boolean ascending) {
    List<T> list = new ArrayList<T>();
    Collections.sort(list);
    return list;
}

我们得到的行Collections.sort(list)中的错误是:

Bound mismatch: The generic method sort(List<T>) of type Collections is not 
applicable for the arguments (List<T>). The inferred type T is not a valid 
substitute for the bounded parameter <T extends Comparable<? super T>>

但是,它适用于以下签名:

<T extends Comparable<T>> List<T> sort(Collection<T> c, boolean ascending);

使用该签名,上面的代码(sort的实现)正如预期的那样工作。我想知道是什么原因。

2 个答案:

答案 0 :(得分:3)

Comparable<T>的列表是与T s相当的对象列表。人们不能说这些对象本身是T。因此,不可能将两个元素相互比较。

偶然与其他T相当的

T可以相互比较。因此,可以对这样的T列表进行排序。

答案 1 :(得分:2)

Collections.sort期望List<T extends Comparable<? super T>>,即编译器需要能够告诉它正在排序的列表的元素类型T扩展Comparable<E>其中{{1} } ET的超类或T实现的接口。您使用T的第一个签名不会强制执行此操作,因此您无法public <T> List<Comparable<T>> sort Collections.sort。你可以通过说

来使它工作
List<T>

匹配sort方法返回的类型,但问题是它相当不灵活 - 它只能对List<Comparable<T>> list = new ArrayList<Comparable<T>>(); 而不是 a Collection<Comparable<Foo>>进行排序Collection<Bar>。最灵活的方法是坚持Bar implements Comparable<Foo>,但使用像

这样的签名
new ArrayList<T>()

<T extends Comparable<? super T>> List<T> sort(Collection<T> c, boolean ascending); 设置最小限制以使排序有效 - 它将与T一起使用,这是您的第二个签名不允许的(需要Bar extends Foo implements Comparable<Foo>)。< / p>