泛型PECS原则理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30496695/article/details/83032189

概念

PECS即 Producer extends Consumer super
即如果参数化类型表示一个T的生产者,使用<? extends T>,如果表示一个T的消费者,使用<? super T>。
再通俗点说:

  • 从集合中取元素, 使用<? extends T>通配符
  • 向集合中放元素, 使用<? super T>通配符

问题

这里仍然使用网上常见的一个例子,Fruit、Apple、RedApple的例子
继承关系为:

RedApple extends Apple

Apple extends Fruit

首先明确一个问题:为什么会出现泛型通配符?

Fruit fruit = new Apple();//没有问题 

List<Fruit> list = new ArrayList<Apple>();//编译不通过 

因为List<Fruit>不是List<Apple>的父类

泛型中List的父类需要用List<? extends Apple>表示

<? extends T>

看一个例子:
在这里插入图片描述
从上面代码中可以看出,向fruitContainer中是不能添加元素的, 但是可以取出Fruit类型的元素

可以这样理解:

  • 泛型就是一个标签,容器上贴上什么标签就只能放对应类别的东西,:苹果容器,:水果容器,<? extends Fruit>:某种水果容器
  • 苹果容器(appleList)只能装苹果,不能装其它水果的,水果容器(fruitList)是可以装各种水果
  • 将一个水果容器(fruitList)贴上<? extends Fruit>标签以后,我们只知道它是放某种水果的容器,并不知道是放那种水果的容器,有可能是放苹果、也有可能是放香蕉的、还有可能是所有水果都能放的
  • 所以要对贴<? extends Fruit>标签的容器进行限制,不允许随意放入水果,假如是苹果容器,结果用户想放入香蕉呢,往外拿是可以的,因为我们知道拿出来的一定是Fruit

<? super T>

在这里插入图片描述

  • 代码中可以看出appleContainer是可以往里放元素的,放的元素只能是Apple以及其子类,取出的元素只能用Object接纳容器在贴上<? super T>标签后,我们只知道它是存放Apple或者是某种父类水果的容器
  • 放入水果时,只要是Apple以及子类都可以放心放入,但是Apple的父类就不能保证一定能放进去了,如果原来是Fruit容器还好,如果是Apple容器,当然不能放入Fruit啊,所以Apple的父类干脆都不让放
  • 取水果时从里面取出来的可能是Apple也可能是其父类,不能确定到底是什么所以只能用顶级父类Object存放

猜你喜欢

转载自blog.csdn.net/qq_30496695/article/details/83032189