理解<? extends T>,<? super T>

<? extends T>:存储的是T或者T的子类

那么根就是T了(上限),由于存储的是T/T子类,所以具体的类型是不确定的(因为不知道存储的是哪一种具体子类),但是里面的类型肯定是属于T基类类型的(因为存储的不管是什么子类类型,都是可以强转为基类的)。从以上分析可以得知,<? extends T>无法往里面存储数据(不知道要存储哪种子类类型),但是可以往里面获取数据(都是T基类类型)。

<? super T>:存储的是T或者T的基类

那么根就是T了(下限),由于存储的都是T/T基类,因此,可以往里面存任意T的子类型(但是不能存储T的基类型,因为T基类有很多种,不能确定是存储哪一种,这种情况跟<? extends T>不能进行add的操作原因是一样的,只是super无法确定存储哪种基类,extends无法确定存储的是哪种子类),获取元素时,由于存储的是T/T基类,无法确定获取的是哪种具体基类类型,所以是无法进行数据获取的(其实获取是可以的,但是获取 到的都是Object类型)。

举例

比如现有一个篮子(集合),篮子里面可以盛放各种水果:

class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}
class Banana extends Fruit{}
class RedOrange extends Orange{}
class GoldenOrange extends Orange{}

那么:

<? extends Orange >存放的可能是RedOrangeGoldenOrange等等中的特定一种,所以在没掀开篮子遮布前,我无法确定篮子放的是具体哪种水果,所以无法进行存(add)操作(因为不知道要存哪种Orange)。但是,就算是闭着眼睛从篮子里拿出一个东西,我肯定知道拿出的是Orange(不管拿出来的是RedOrangeGoldenOrange还是什么,反正都是Orange),所以取(get)操作可行。

<? super Orange>存放的可能是OrangeFruit中的特定一种,所以在没掀开篮子遮布前,我无法确定篮子放的是具体哪种水果,所以无法进行取(get)操作(有可能拿出来的是Orange,有可能是Fruit)。但是,只要是往里面存放Orange类型水果,那么是绝对是可以的(因为篮子里面的是Orange或者Fruit中特定水果,那么RedOrangeGolenOrange也是属于OrangeFruit呀)。

总结

<? extends T>可以获取数据(get T类型),无法存储数据(add)。
<? superT>可以存储数据(add T及T的子类),无法获取数据(get)。

什么时候要使用<? extends T>,<? super T>呢,请记住下面这句话:

  • 如果你是希望调用T方法,那么使用<? extends T>,因为你可以进行取操作(get)。
  • 如果你是希望往容器里面存数据,那么使用<? super T>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,027评论 19 139
  • 前言 泛型(Generics)的型变是Java中比较难以理解和使用的部分,“神秘”的通配符,让我看了几遍《Java...
    珞泽珈群阅读 7,949评论 12 51
  • java泛型解决容器,不确定类型问题,多个返回值,避免类型转换。 类泛型 类泛型定义的时候需要在类型后增加尖括号,...
    wangsye阅读 459评论 0 0
  • SwipeMenuListView类 涉及到的一些知识点,在onInterceptTouchEvent方法的dow...
    最美下雨天阅读 287评论 0 0
  • 上一章 残花月圆看不见。落叶飘零路不清。随风遇浪行万里,冬作枯泥又逢春。 吴文殊,1960年出生于日本古屋,七岁那...
    TYH简学堂阅读 335评论 0 0