目录

基础知识点

上限通配符

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. python3.6.4安装教程-python3.6.4如何安装到树莓派3代
  2. wp7技术类网站汇总
  3. C++(2)--代码结构
  4. nodejs 创建一个静态资源服务器 +路由
  5. MySQL主从失败:slave_IO_Running为No
  6. JVM内存分析及导致内存溢出的不健壮代码及解决办法
  7. linux内核模块的程序结构
  8. PHP留言并展示_留言页面展示功能
  9. SQL Azure 服务器端架构
  10. Python全栈学习_day010作业
  11. oracle必须配置哪个参数,oracle – 此操作必须将ORA-02069 global_names参数设置为TRUE...
  12. 高斯误差函数erf的数值计算方法(C++实现)
  13. PDF怎么编辑,如何给PDF添加书签
  14. 系统重装后恢复MySQL数据
  15. 单片机c语言程序编写步骤,Proteus运行Keil编写的51单片机C语言步骤
  16. 服务器虚拟机双活,VMware双活数据心解决方案详解.pptx
  17. 【可视化开发】数据大屏可视化技术汇总
  18. Dijkstra算法指定任意两点距离(邻接矩阵法)
  19. android 自定义 对号,Android 自定义View 对勾CheckBox
  20. 编写windbg调试器扩展 入门篇1

热门文章

  1. 博图14软件安装顺序_请教关于博途软件中各个部分的安装顺序和注意事项。
  2. C/C++-----对C语言文件的学习
  3. 概要索罗斯的金融炼金术
  4. java中通过split方法使用分号分割,使用正则表达式匹配不识别单引号中的分号
  5. 机器人操作——diffusion policy(2023)
  6. 我国利用大数据反恐有待加强
  7. 什么是CPS什么是CPT
  8. 对一维二维三维数组的分析 及其 np.shape 的输出
  9. 汉服重现与中国的文艺复兴
  10. 培训完软件测试后,真的可以找到工作吗?