java泛型中的PECS原则Producer extend consumer super和上限和下限解释

关注公众号:”奇叔码技术“

回复:“java面试题大全”或者“java面试题”
即可免费领取资料




一、适用场景:学好了能够看懂Stream类中的一些方法参数;了解概念:限制上限【可以返回值】和下限【可以添加值】和PECS原则【限制了数据的放入和取出。】


1、什么叫上限?

//上限:这个箱子容器最大为100,但是具体可以放多小的东西谁也不知道,放80,79,40,最后确定它可以放30,那都错误了,所以,没有明确的说明,那就不可以放东西为100以下的;
// 例如:我看起来最大20岁,那你可以说我18,19,15都行,但是如果我是15,那18和19就错误了;


//但是,这个箱子容器最大为100,我可以拿一个100的容器或者200的容器总之大于等于100的容器,把它装起来,所以,它是用来取即有返回值,不能放;


//又,生产者是不断创造东西得,上限就像工厂里面生产东西 【返回东西】,他就是生产者;

2、什么叫下限?

//同理:
// 下限:这个箱子容器最小为100,那我可以放比100还小的东西进去;我可以放80都行;所以,它是用来放得,不是用来取得;


//又,消费者是用东西的;下限就是我有钱,我去银行存钱,我就把钱消费给了银行;【感觉不恰当】

二、通配符<?>和类型参数T、K、V的区别?

//通配符<?>和类型参数的区别就在于,对编译器来说所有的T都代表同一种类型。比如泛型方法里,三个T都指代同一个类型,要么都是String,要么都是Integer。
//但通配符<?>没有这种约束,List<?>单纯的就表示:集合里放了一个东西,是什么我不知道。
//实际就是类型参数指明了类型,编译器知道你是什么类型;
//通配符<?>没有约束,是什么类型的我是问号不知道的,所以不能放东西;
//如果是<? extends Father > 指明上限是Father,而?是它的子类或者就是Father;


//如果是需要获取值,那就只能是利用 多态 返回的类型必须是它的基类【即父类或者自己】

三、PECS原则

/*PECS原则【限制了数据的放入和取出。】
最后看一下什么是PECS(Producer Extends Consumer Super)原则,已经很好理解了:
频繁往外读取内容的,适合用上界Extends。知道上界限 即 可以通过多态向上转型 返回其基类 Object、父类、自己、
经常往里插入的,适合用下界Super。 知道下界限 即 可以通过多态向上转型 添加其子类 子类、自己;

PESC = producer-extens , consumer -super.
如果参数化类型表示一个 T 生产者,就使用 <? extends T>; 如果它表示一个 T 消费者, 就使用 <? super T>
PESC 这个助记符突出了通配符类型的基本原则。(Get and Put Principle)

范型为List<?extends A> list,确定了上界为A,list是一个生产者,可以从list中取出数据;
为List<? super A> list,确定了下界,list 中的数据类型为A 或者A的父类,list是一个消费者:

四、上代码:

package com.jiqi.Stream;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {
    
    public static void main(String[] args) {


    }
    //<? super Father> ?比 Father还要super【大】 那Father就是最小的,即下界限 那可以放比Father还要小的;
    public void floorLimit(){
        ArrayList<? super Father> list = new ArrayList<>();
        boolean add = list.add(new Son());
        boolean add1 = list.add(new Father());
        boolean add2 = list.add(new LeiFeng());
        System.out.println(add);
        System.out.println(add1);
        System.out.println(add2);
        Object object = list.get(0);
        System.out.println(object);
    }
    //<? extends Father> ?继承于 Father 比Father 【小】 naFather就是最大的,即上界限 那可以返回比Father大的;
    public void upLimit(){
        List<? extends Father> list = new LinkedList<>();
        // list.add(new Son()); 报错,虽然是它的子类,符合 son extends Father ;
        // 但由于?通配符 是一个问号他不知道里面放了什么东西,所以编译报错;

        //赋值是合法的
        List<? extends Father> list1 = new ArrayList<Father>();
        List<? extends Father> list2 = new ArrayList<Son>();
        List<? extends Father> list3 = new ArrayList<LeiFeng>();
        //取值可以,只能利用多态的形式 进行获取;
        Object o  = list.get(0);
        Father f  = list.get(0);
        Human h  = list.get(0);
        //上界<? extends T>不能往里存,只能往外取
    }
}
class Human{
}
class Father extends Human{
}
class Son extends Father{
}
class LeiFeng extends Father {
}

点击跳转学习大佬的借鉴题目:Java中<? extends T>和<? super T>的理解#

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值