java 泛型<? super T>和<? extends T>

本文以list为例,其他集合类似。
为了安全,编译器在List进行存储的时候只会保存为一种类型。

List<? super T> list中的元素全是T的某个父类型
List<? extends T> list中的元素全是T的某个子类类型

上面这种定义类型的使用场景:

PECS指“Producer Extends,Consumer Super”。换句话说,如果参数化类型表示一个生产者,就使用<? extends T>;如果它表示一个消费者,就使用<? super T>。

在实际的使用中,<? extends T> 实际上代表的是T的某个子类<X>,X继承自T,当我们插入一个数据T的时候无法保证其能够转换成X,但是我们可以保证读取的数据可以转换成T。
同理<? super T>实际上也是代表的T的某个父类<Y>,当我们读取一个数据的时候是无法保障Y能够转换成T的,但是能够保障插入T数据能够转换成Y。

由于List<? extends T>是list中的某个子类,如果我们向list中添加元素,子类之间并不能相互转换,导致添加失败,而List<? super T> 则可以用来添加T的子类,因为T的子类型都可以转为T的某个父类。 相反List<? extends T>中的元素则都可以转为T,则可以用来读取list中的元素,但是List<? super T> 中的元素不能转为T则无法用来读取list中的元素,除非读取为Object 类型。
这样这两个类型的用途就很明显:

List<? super T> 保证向list中添加的元素全是T的子类含T,用于只写操作,读操作可能会导致异常
List<? extends T> 保证读取list中的元素全是T的子类含T ,用于只读操作,写操作会有异常

用例(java.util.Collections的copy方法):

    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());
            }
        }
    }

保证dest只用来存储数据,src的数据只会被读取。
附加:
对于实现了RandomAccess接口的列表,随机读取的效率高于迭代器,而没有实现RandomAccess的接口的列表使用迭代器效率要高一些。(Java接口RandomAccess全面了解

参考
Java 泛型详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 泛型 泛型(Generic Type)简介 通常情况的类和函数,我们只需要使用具体的类型即可:要么是基本类型,要么...
    Tenderness4阅读 1,447评论 4 2
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 2,031评论 0 3
  • 第8章 泛型 通常情况的类和函数,我们只需要使用具体的类型即可:要么是基本类型,要么是自定义的类。但是在集合类的场...
    光剑书架上的书阅读 2,159评论 6 10
  • 今天是国庆假期最后一天,也是比较忙碌的一天。爷爷还没有回来,老公今天有事也没在家,上午女儿自己骑车去英语班,家...
    累并幸福着阅读 230评论 0 0
  • 表层习惯完成情况:早起(低)听力(低)阅读(低) 最晚和朋友聊天到很晚,早上起不来。悲伤 还是得早睡啊 不早睡哪来...
    呀呀呀呀呀dream阅读 168评论 0 0