• Java泛型通配符


    前言

    String是Object的子类,因此下面的代码是合法的。

    Object obj = new String();
    

    但是,下面这段代码是不合法的。

    ArrayList<Object> list = new ArrayList<String>();
    

    原因就是,泛型是不变的(invariant)。泛型通配符就是解决这一问题的,可以增大代码的灵活性。

    <? extends E>

    <? extends E>是上限通配符,限定了类型的上限(这里的上,指的的是类继承图中的位置),?必须是E的子类。
    以下图的继承关系为例,这些代码都是合法的。

    ArrayList<? extends animal> list = new ArrayList<animal>();
    ArrayList<? extends animal> list = new ArrayList<cat>();
    ArrayList<? extends animal> list = new ArrayList<dog>();
    

    存入元素

    由于<? extends E>只指定了类型的上限,因此,list中存放的是E的子类,但编译器无法确定是哪个子类,因此无法加入元素。例如:

    ArrayList<? extends animal> list = new ArrayList<cat>();
    list.add(new dog());
    

    虽然dog是animal的子类,但是,此时的list实际上是指向ArrayList的,那么必然会引起错误。

    取得元素

    由于<? extends E>指定了类型的上限,因此,我们获得的所有元素,都是animal的子类,因此下面的语句是合法的。

    ArrayList<? extends animal> list = new ArrayList<cat>();
    animal t = list.get(0);
    

    <? super E>

    <? super E>是上限通配符,限定了类型的上限,?必须是E的父类。

    存入元素

    list中存放的是E或E的父类,因此,list是一定可以存储EE的子类的。因此下面的代码是合法的。

    ArrayList<? super dog> list = new ArrayList<animal>();
    list.add(new dog());
    

    取得元素

    list中存放的是E或E的父类,因此,我们只能确定,我们所取得的元素是Object的子类。因此下面的代码是合法的。

    ArrayList<? super dog> list = new ArrayList<animal>();
    Object obj = list.get(0);
    

    PECS法则

    PECS是"Producer-extends, Consumer-super"的简写。
    我们看到,<? extends E>适合于取元素的场景(生产者);<? super E>可以存入E类型的数据,适合于取元素的场景(消费者)。
    如果是既要存、也要取的集合,那么不适合使用泛型通配符。

  • 相关阅读:
    窗口和消息
    输出文字
    《windows程序设计》第一章,建议想学API的每天看一章
    hdu 1008为何不对?求大神指导!
    课程设计(物体类),图片可能没有加载出来,自己运行一下就行了
    二叉树前序、中序、后序遍历相互求法
    哈希表工作原理
    c++中关于static关键字的问题
    Halcon学习笔记之缺陷检测(二)
    Halcon学习笔记之缺陷检测(一)
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/13455567.html
Copyright © 2020-2023  润新知