<? extends T>与<? super T>的区别

Posted 爱叨叨的程序狗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了<? extends T>与<? super T>的区别相关的知识,希望对你有一定的参考价值。

PECS

来自《Effective Java》的一句话,producer-extends,consumer-super,两者通过规定上下界的形式来做数据限制。


demo

class Fruit 


class Apple extends Fruit 


class Jonathan extends Apple 


class Orange extends Fruit 

代码继承关系:

Jonathan extennds Apple

Apple extends Fruit

<? extends T>

限制生产者的数据来源。

可见,使用通配符引入逆变时,使用<? extends T>指定了泛型的下界为Apple,即只能Apple的父类做List操作才安全,对于Apple的子类是不安全的。

<? super T>

限制消费者数据流入。

在数据流入时,apples可以使用Apple本身的实例和Apple子类放入List中,但是不允许Apple的父类存放,这就限制了数据的使用类型。

// Collections.java
public static <T> void copy(List<? super T> dest, List<? extends T> src) 
    int srcSize = src.size();
    if (srcSize > dest.size())
        throw new IndexOutOfBoundsException("Source does not fit in dest");

    if (srcSize < COPY_THRESHOLD ||
        (src instanceof RandomAccess && dest instanceof RandomAccess)) 
        for (int i=0; i<srcSize; i++)
            dest.set(i, src.get(i));
     else 
        ListIterator<? super T> di=dest.listIterator();
        ListIterator<? extends T> si=src.listIterator();
        for (int i=0; i<srcSize; i++) 
            di.next();
            di.set(si.next());
        
    

复制的target只能是泛型T的实例对象或泛型T的子类。

复制的src只能是泛型T的实例对象或泛型T的父类。

// Collections.java
public static <T> void copy(List<? super T> dest, List<? extends T> src) 
    int srcSize = src.size();
    if (srcSize > dest.size())
        throw new IndexOutOfBoundsException("Source does not fit in dest");

    if (srcSize < COPY_THRESHOLD ||
        (src instanceof RandomAccess && dest instanceof RandomAccess)) 
        for (int i=0; i<srcSize; i++)
            dest.set(i, src.get(i));
     else 
        ListIterator<? super T> di=dest.listIterator();
        ListIterator<? extends T> si=src.listIterator();
        for (int i=0; i<srcSize; i++) 
            di.next();
            di.set(si.next());
        
    

以上是关于<? extends T>与<? super T>的区别的主要内容,如果未能解决你的问题,请参考以下文章

Java 泛型 lt;super T>中 super 怎么 理解?与 extends 有何不同

Java 泛型 lt;super T>中 super 怎么 理解?与 extends 有何不同

? extends T 和 ? super T

java中泛型限定<? extends Comparable<? super T>> 和 <T extends Comparable<? super T>&g

Java泛型 通配符? extends与super

泛型中? super T和? extends T的区别