zoukankan      html  css  js  c++  java
  • 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类型的数据,适合于取元素的场景(消费者)。
    如果是既要存、也要取的集合,那么不适合使用泛型通配符。

  • 相关阅读:
    C++ std::stack 基本用法
    linux6 安装 ntopng
    linux 6安装 redis2.6
    Linux6搭建Tomcat服务器
    EXSI6.5忘记root密码
    python3笔记--数字
    python3笔记--运算符
    python3基本数据类型
    python3笔记
    centos6.X升级python3.X方法
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/13455567.html
Copyright © 2011-2022 走看看