<? 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 有何不同
java中泛型限定<? extends Comparable<? super T>> 和 <T extends Comparable<? super T>&g