目录

基础知识点

上限通配符

List中上限通配符的add()方法

List中上限通配符的get()方法

下限通配符

List中下限通配符的add()方法

List中下限通配符的get()方法


基础知识点

开始先了解一下基础知识点:

在Java中,向上转型是允许的,但向下转型会无法编译通过。如果强转,有可能会抛出ClassCastException异常。那么如果真要向下转型,平时我们要一般都会先用instanceof来判断是否是这个类型,如果是,才进行强转。

废话不多说,上代码:

class A {
}class B extends A {
}class C extends B {
}

上限通配符

上限通配符:? extends B  ,表示某类型的父类是B(或者说,某类型继承于B),它和类的extend是一样的。

List中上限通配符的add()方法

它负责放入一个某种类型的对象到List中。在下面这个代码块代码中,这个某种类型肯定是B的子类类型。

List<? extends B> extendList = new ArrayList<>();
extendList.add(new Object());//编译报错
extendList.add(new A());//编译报错
extendList.add(new B());//编译报错
extendList.add(new C());//编译报错
extendList.add(null); //可以放入,因为null不是有效的对象实例。

为什么除了add(null),其它的都不能通过编译呢?
        因为编译器只知道extendList应该放入B的子类,但并不知道放B的哪个子类。也就是说如果B有1万个子类,某种类型就有1万种类型的可能,这个时候没办法判断它具体是那个类型。由于编译器不懂是B的哪个子类,在执行add方法时,无法进行类型转换成某个指定的类放入List,所以只能放入null,而不能放入其它的对象。
        有人可能会说为啥Object也不行?因为Object是所有类的父类,但是由于向下转型正常也是编译不通过的,所以也不能放入。

List中上限通配符的get()方法

它负责从某种类型的List方法中返回某种类型的值。在下面这个代码块中,这个某种类型是B的子类型,加上在java中向上转型是允许的,所以可以返回类型为B及其父类型的值(例如:A类型,以及所有类的父类Object)。但是编译器依旧不能确定是B类型的哪个子类,所以就算B类型只有一个子类C,也不能直接返回C类型的对象(除非强转)。

注:它就是PECS中的PE,即produce  ->  extend  ,下面代码中表示List是生产者,你只能从这个List里面往外面拿(给别人)。

List<? extends B> extendList = new ArrayList<>();
B b = extendList.get(0);//正常
A a = extendList.get(0);//正常向上转型
C c = extendList.get(0);//编译报错

下限通配符

下限通配符:? super B  ,表示某类型是B的父类型,和代码中调用父类方法的super关键字类似。

List中下限通配符的add()方法

它负责放入一个某种类型的对象到List中。在下面这个代码块代码中,这个某种类型肯定是B的父类类型。

注:它就是PECS中的CS,即consumer  ->  super ,下面代码中表示这个List集合是消费者,你只能往里面放(给它消费)。

List<? super B> superList = new ArrayList<>();
superList.add(new Object());//编译报错
superList.add(new A());//编译报错
//某种类型肯定是B的父类型,所以只能放入B或B的子类,才能向上转型
superList.add(new B());
superList.add(new C());
superList.add(null); //可以放入,因为null不是有效的对象实例。

为什么这个List<? super B>可以执行add方法呢?
        虽然编译器可以知道B的所有父类,但是它也没法知道这个某种类型具体是B的哪一个父类类型,所以你可以放入B及B的子类型(向上转型)。

List中下限通配符的get()方法

因为编译器不懂返回的是什么类型,只知道是B类型的父类,所以只能返回一个Object(因为它是所有类的父类)。

Object object = superList.get(0);//正常
A a1 = superList.get(0);//编译报错
B b1 = superList.get(0);//编译报错
C c1 = superList.get(0);//编译报错
 

泛型通配符之PECS相关推荐

  1. 学员优秀博文赏析:泛型通配符及约束

    最课程师徒班的同学正在红红火火的学习中.仿佛.应该.必须,到了跟大家阶段性汇报成果的时候了.为什么,因为毕竟当时把师徒班说的那么好,就业班的同学该要闹革命了. 师徒班相较于就业班,虽然课程内容和总量完 ...

  2. java pecs_『Java』泛型中的PECS原则

    Java编程中有时我们要用到不确定的元素,通常用通配符"?"表示,其中" ? extends T "叫"上界通配符", " ? s ...

  3. 泛型(派生子类,泛型通配符,类型擦除)

    目录 从泛型类派生子类 1.子类不是泛型类,明确父类类型 2.子类和父类都是泛型类 泛型通配符 1.类型通配符上限 2.类型通配符下限 类型擦除 从泛型类派生子类 1.子类不是泛型类,明确父类类型 c ...

  4. [转]JAVA泛型通配符T,E,K,V区别,T以及ClassT,Class?的区别

    原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...

  5. 不正确 有三种形式 说法 通配泛型_一看就懂 详解JAVA泛型通配符T,E,K,V区别...

    1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛 ...

  6. 【Java 泛型】泛型用法 ( 泛型类用法 | 泛型方法用法 | 泛型通配符 ? | 泛型安全检查 )

    文章目录 一.泛型类用法 二.泛型方法用法 三.泛型通配符 <?> 四.泛型安全检查 五.完整代码示例 1.泛型类 / 方法 2.main 函数 一.泛型类用法 泛型类用法 : 使用时先声 ...

  7. java 文件通配符_Java中泛型通配符的使用方法示例

    本文实例讲述了Java中泛型通配符的使用方法.分享给大家供大家参考,具体如下: 一 点睛 引入通配符可以在泛型实例化时更加灵活地控制,也可以在方法中控制方法的参数. 语法如下: 泛型类名 extend ...

  8. java学习(134):泛型通配符的使用

    import java.util.ArrayList; import java.util.List;//泛型通配符的使用 public class test73 {public static void ...

  9. java for(o t :object) 获取顺序号_JAVA泛型通配符T,E,K,V区别 瞬间豁然开朗

    1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛 ...

最新文章

  1. (转)动态SQL和PL/SQL的EXECUTE IMMEDIATE选项
  2. leetcode-581-Shortest Unsorted Continuous Subarray
  3. mysql 匹配所有记录_如何记录mysql中所有的查询
  4. 浅谈CSS3中的弹性布局
  5. 导致集群重启_园区网核心交换机S7706异常重启导致无线网络故障
  6. 全国计算机二级雷同卷怎么处理,信息系统项目管理师考试结束后,雷同卷怎么判定你知道吗?...
  7. 学习BIOS与CMOS区别
  8. Linux知识--初始linux
  9. 对数组名取地址a和 数组首地址a
  10. 柔性太阳能电池pdf_CIS太阳能电池.pdf
  11. Go测试远控免杀学习
  12. Centos 7系统密码破解
  13. Html5代码实现动态时钟
  14. 基于Java的奖学金评定管理系统
  15. 关闭msmpeng_你知道吗?把电脑系统里的这些进程关闭掉,可以提升系统流畅
  16. 测试小故事74:没有计划的日子
  17. latex 行内公式和行间公式高亮问题、多行高亮问题
  18. 前端进击的巨人(六):知否知否,须知this
  19. mimo节能模式smps_SMPS的完整形式是什么?
  20. 专线网络与家庭宽带区别(基础篇)

热门文章

  1. 未来的大数据会有哪些有趣的发展?
  2. matlab函数im2bw_matlab函数大全
  3. gulp4.0构建自动化项目
  4. 北科天绘 16线3维激光雷达开发教程
  5. c# 生成二维码图片
  6. linux查看系统内存的命令
  7. 8步安装多多客小程序全插件化1.0开源版
  8. qnx如何和Android传递数据,QNX操作系统下MDSL数据记录和转存的研究与实现
  9. 直方图规定化——GML和SML映射规则
  10. 入行IT学习web前端的优势