zoukankan      html  css  js  c++  java
  • PECS 泛型参数 逆变/协变/不变/无关

    T 用于泛型类和泛型方法的定义

    ?用于泛型方法的调用和形参

    T 只有extends一种限定方式,<T extends List>是合法的,<T super List>是不合法的

    PECS

    生产者(Producer)使用 extends,消费者(Consumer)使用 super。

    逆变与协变用来描述类型转换(type transformation)后的继承关系,其定义:如果AA、BB表示类型,f()f(⋅)表示类型转换,≤表示继承关系(比如,ABA≤B表示AA是由BB派生出来的子类);

    • f()f(⋅)是逆变(contravariant)的,当A时有f(B)≤f(A)成立;
    • f()f(⋅)是协变(covariant)的,当A时有f(A)≤f(B)成立;
    • f()f(⋅)是不变(invariant)的,当A时上述两个式子均不成立,即f(A)f(B)相互之间没有继承关系。

     数组是协变,泛型不是协变的,泛型具有无关性,不具备子父类关系

    Number[] numbers = new Integer[3];

    <? extends>实现了泛型的协变

      List<? extends Number> list = new ArrayList<Integer>();

    <? super>实现了泛型的逆变

      List<? super Number> list = new ArrayList<Object>();

    <? super Number>表示list所持有的类型为在Number与Number的基类中的某一类型,其中Integer与Float必定为这某一类型的子类;所以add方法能被正确调用。

    List<? super Number> list = new ArrayList<Object>();

    list.add(new Integer(1));

    list.add(new Float(1.2f));

    生产者,写入/添加   ??

    站在谁的角度??生产消费?   容器的角度,吃进去,吐出来

    消费者,读取/获取  ??

    如果你是想遍历collection,并对每一项元素操作时,此时这个集合是生产者(生产元素),应该使用 Collection<? extends Thing>.

    如果你是想添加元素到collection中去,那么此时集合是消费者(消费元素)应该使用Collection<? super Thing>

     最大接收。

    <? extends Person> 上界--无穷小,小,岂止与小   

    get() 出来只确定最大是Person,最小不知道,故用Student接收错误(多态,子类 = 父类  不允许,  父类 = 子类  允许

    list1.add(Student )  错误    ?可能比Student还想小     ? << Person 

    <? super Person> 下届-无穷大,大,岂止与大

    list2.add(Student )  正确  多态   ? >> Person 子类Student

    list2.add(Person父类 ) 错误   ?可能在中间,不符合多态

    PECS总结:指”Producer Extends, Consumer Super”

         如果你想从一个数据类型里获取数据,使用 ? extends 通配符

        如果你想把对象写入一个数据结构里,使用 ? super 通配符            super add 的笑容  消费者

        如果你既想存,又想取,那就别用通配符。

    泛型方法  E 与 泛型类 T 没关系

     super add

    泛型没有协变性,通配符使得容器有协变性!

      拿出上界,添加下界,保证容器协变性

     Java8 Stream  

    又如何解释??
    Supplier<? extends T> s   生产者
    void forEach(Consumer<? super T> action);  流容器消费
    Stream<T> filter(Predicate<? super T> predicate);  容器消费数据
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
    Function<? super T 进去  消费者
    ? extends R> mapper 出来 生产者

    深入泛型,以下链接很好,难懂

    https://www.cnblogs.com/en-heng/p/5041124.html

    https://blog.csdn.net/zy_jibai/article/details/90082239

  • 相关阅读:
    【LeetCode OJ】Longest Substring Without Repeating Characters
    JavaScript学习笔记一
    Struts2(五)数据校验
    Struts2(四)属性驱动和模型驱动
    php知识大集合(自用)
    正则表达式匹配非需要匹配的字符串(标题自己都绕晕了)
    php中ereg() ,preg_match() 与preg_match_all的区别?代码详细比较
    linux 查询当前文件夹下的目录数量
    linux 下如何查看mysql跑了哪些服务
    mysql同主机下 复制一个数据库所有文件到另一个数据库
  • 原文地址:https://www.cnblogs.com/daofree/p/15644905.html
Copyright © 2011-2022 走看看