什么是<! - ?超级T - >语法?

时间:2010-05-13 14:28:39

标签: java

我无法理解以下语法:

public class SortedList< T extends Comparable< ? super T> > extends LinkedList< T >

我看到类SortedList扩展了LinkedList。我只是不知道是什么

T extends Comparable< ? super T>

的装置。

到目前为止,我对它的理解是类型T必须是实现Comparable的类型......但是什么是< ? super T >

5 个答案:

答案 0 :(得分:91)

泛型中的超级是扩展的反面。而不是说可比较的泛型类型必须是T的子类,它说它必须是T的超类。区别很重要因为extends告诉你你可以从一个类中获得什么(你得到的至少是这个,也许是一个子类)。 super告诉你你可以把什么放进课堂(最多这个,也许是一个超类)。

在这种特定情况下,它所说的是该类型必须实现其自身或其超类的可比性。所以考虑java.util.Date。它实现了Comparable<Date>。但是java.sql.Date怎么样?它也实现了Comparable<java.util.Date>

如果没有超级签名,SortedList将无法接受java.sql.Date的类型,因为它本身并不实现Comparable,而是实现自身的超类。

答案 1 :(得分:81)

这是一个较低限度的通配符。

JLS 4.5.1 Type Arguments and Wildcards

  

通配符在需要仅部分了解类型参数的情况下非常有用。 [...]上限由语法表示:

? extends B
     

其中B是上限。 [...]允许使用以下语法声明通配符的下限:

? super B
     

其中B是下限。

例如,List<? super Integer>包括List<Integer>List<Number>List<Object>

通配符用于使泛型更强大和灵活;边界用于维护类型安全。

另见


至于<T extends Comparable<? super T>>中这是如何有用的,那就是Cat extends Animal implements Comparable<Animal>之类的内容。

查看Collections.sort

的签名
public static <T extends Comparable<? super T>> void sort(List<T> list)

因此,使用List<Cat> listOfCat,您现在可以Collections.sort(listOfCat)

如果声明如下:

public static <T extends Comparable<T>> void sort(List<T> list)

然后您必须Cat implements Comparable<Cat>才能使用sort。通过使用? super T有界通配符,Collections.sort变得更加灵活。

另见

  • Effective Java 2nd Edition,Item 28:使用有界通配符来提高API灵活性
    • 此外,PECS原则:“生产者extends消费者super

答案 2 :(得分:10)

这意味着T必须实施Comparable<T itself or one of T's superclasses> 感觉是因为SortedList已排序,它必须知道如何比较其泛型T参数的两个类。这就是T必须实施Comparable<T itself or one of T's superclasses>

的原因

答案 3 :(得分:5)

这意味着T类型必须实现Comparable或其中一个超类的T

例如,如果A延伸B,如果您要使用SortedList<A>,则A必须实施Comparable<A>Comparable<B>,或者实际上只是Comparable

这允许使用任何有效的比较器构建A的列表。

答案 4 :(得分:4)

考虑以下示例:

  1. 使用类声明中定义的类型参数

    public class ArrayList扩展AbstractList ... {
         public boolean add(E o)//你可以在这里使用“E”,因为它已被定义为类的一部分

  2. 使用未在类声明中定义的类型参数

    public <T extends Animal> void takeThing(ArrayList<T> list)
                                                // Here we can use <T> because we declared "T" earlier in the method declaration                  
    

    如果类本身不使用类型参数,您仍然可以通过在返回类型之前在异常(但可用)空间中声明它来为方法指定一个。这种方法说T可以是“任何类型的动物”。

  3. 注意:

    public <T extends Animal> void takeThing(ArrayList<T> list)             
    
    is NOT same as              
    
    public void takeThing(ArrayList<Animal> list)
    

    两者都是合法的,但它们是不同的。第一个表示您可以传入实例化为Animal的ArrayList对象或任何Animal子类型,如ArrayList,ArrayList或ArrayList。但是,您只能在第二个传递ArrayList,而不能传递任何子类型。