java PECS以及 通配符? 和T

首先说一下PECS 原则,有过写泛型代码的朋友对此都不陌生,今天也遇到类似的问题,简单记录一下。

1.如果要从集合中读取类型T数据,并且不能写入,可以使用 ? extends E 通配符 ;接受E类型或者E的子类型

2.如果要向集合里写入类型T数据,并且不需要读取, 可以使用 ? super E 通配符; 接收E类型或者E的父类型

3.如果既要存又要取,那么就不要使用任何通配符

具体测试代码如下:

import java.util.ArrayList;
import java.util.List;

/**
 * Created by passself on 2018/8/2.
 */
public class PECS {
    static class Food{}
    static class Fruit extends Food{}
    static class Apple extends Fruit{}

    public static void main(String[] args) {
        List<? extends Fruit> fruits = null;//new ArrayList<>();//编译错误
        //fruits.add(new Food());
        //fruits.add(new Fruit());
        //fruits.add(new Apple());//编译器只是知道fruits 是Fruit 的某个子类,并不知道这个子类具体是什么,为了类型安全,只好阻止向其中加入任何类型
        fruits = new ArrayList<Fruit>();
        fruits = new ArrayList<Apple>();
        //fruits.add(new Fruit());
        //fruits = new ArrayList<Food>();//编译错误

        //fruits = new ArrayList<? extends Fruit>();

        Food food = fruits.get(0);

        //使用super 效果 表示类型的下界是 T,参数化类型可以是 T 或 T 的超类:
        List<? super Fruit> tempFruits = null;
        tempFruits = new ArrayList<Fruit>();
        tempFruits = new ArrayList<Food>();
        //tempFruits = new ArrayList<Apple>();//编译错误

        tempFruits.add(new Fruit());
        tempFruits.add(new Apple());
        //tempFruits.add(new Food());//编译错误,出于对类型安全的考虑(编译器会自动向上转型),只能加入fruit或者其子类,因为不知道是哪个超类

        //Fruit fruit = tempFruits.get(0); //编译错误 编译器并不知道超类具体是什么类,只能返回Object对象,因为Object是任何java类的超类
        Object object = tempFruits.get(0);


    }

    /**
     * 说明:
     * 如果要从集合中读取类型T数据,并且不能写入,可以使用 ? extends E 通配符 ;接受E类型或者E的子类型
     * 如果要向集合里写入类型T数据,并且不需要读取, 可以使用 ? super E 通配符; 接收E类型或者E的父类型
     * 如果既要存又要取,那么就不要使用任何通配符
     */
}

其中注释部分是无法编译成功的,也标注相关解释。

补充:

上面正好提到了通配符?来看一下和我们常用的 T通配符的区别.
? 代表不清楚到底是怎样的类型
T 是限定了相关的类型"T"
比如:
List<T> al=new ArrayList<T>();指定集合元素只能是T类型
List<? extends E> al=new ArrayList<? extends E>(); 只是知道是E的子类,并不知道是哪个子类,?通配符一般不单独使用,因为单独使用也没有意义,比如:List<?> al=new ArrayList<?>();
使用方式有? extends E 或者? super E

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

推荐阅读更多精彩内容

  • 前言 泛型(Generics)的型变是Java中比较难以理解和使用的部分,“神秘”的通配符,让我看了几遍《Java...
    珞泽珈群阅读 12,395评论 12 51
  • 在泛型概述-基本概念当中,我们介绍了有关类型参数限定的概念,使用 extends 关键字,给类型参数加以限定,例如...
    realxz阅读 4,093评论 0 1
  • 泛型 对象和实例是一个意思,类与对象的关系就像数据类型和变量一样。 泛型的主要目的之一就是用来指定类(如:容器)要...
    yueyue_projects阅读 3,652评论 0 0
  • 她到伦敦是在中午十一点半,这周是她们学校的reading week,也恰好我们没课,所以她想来伦敦找我。 考虑到我...
    一目RyanLee阅读 1,651评论 1 2
  • 前两天下班晚,来到校门口,小摊贩们开始收拾自己的物料。偶遇一对商贩的对话 男:收拾好了么? 女:“还差一个凳子” ...
    浅情知阅读 3,352评论 2 2