温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java泛型的PE和CS原则说明

发布时间:2021-09-04 11:48:46 来源:亿速云 阅读:161 作者:chen 栏目:大数据

这篇文章主要讲解了“Java泛型的PE和CS原则说明”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java泛型的PE和CS原则说明”吧!

什么是 PE,CS

PE,CS全称是producer extends,consumer super的缩写,这是 Joshua Bloch 在 Effective Java 一书 中引入的一个略显奇怪的术语,但有助于理解泛型的用法。换言之,参数化类型代表 生产者(producer)则使用 extends, 代表消费者(consumer)则使用 super

PE 原则

简单来说, PE 表示,如果你的方法只是想从集合获取值,并且希望集合的类型范围是T及其子类,那么泛型可以定义为 ? extends T

了解泛型的同学应该知道 extends 是上界通配符,使用了上界通配符,只能读取值,不能写入值,取值的的类型是T

只能取值不能写入的就是生产者,有人可能有点理解了,我们来个更详细的解释,举个栗子

假设,我们有个水果的对象,水果类有个addAll方法,用来将另一个水果集合,放入到水果对象内

class Fruit{
    private List<Fruit> fruits = new LinkedList<>();

    public void addAll(List<Fruit> fruits){
        for (Fruit fruit : fruits) {
            this.fruits.add(fruit);
        }
    }
}

现在,我们需求变了,有苹果,香蕉分别继承了水果这个类,如果我么将苹果或者香蕉集合直接放入addAll方法,会编译报错,因为苹果集合,不是水果集合

public static void main(String[] args){
        List<Apple> appleList = new LinkedList<>();
        Fruit fruit = new Fruit();
        // 编译报错
        fruit.addAll(appleList);
}

class Apple extends Fruit{
}
class Banana extends Fruit{
}

如果我们要放进去怎么办,使用上界通配符,修改addAll方法,使用了上界通配符后,元素只能读,不能写,传入的集合类型范围是Fruit或者其子类集合

public void addAll(List<? extends Fruit> f){
    for (Fruit fruit : f) {
        this.fruits.add(fruit);
    }

有人会问了,这个上界通配符,跟PE有什么关系? 当然有,PEproducer extends的缩写,我们仔细看看,对于addAll方法来说,只是要消费入参,那么入参就是生产者,说着这,估计很多人已经明白了

PE是针对方法来说的,如果某个方法的入参,需要一个生产者,并且范围是泛型的子类,那么使用上界通配符extends

CS 原则

简单来说, CS 表示,如果你的方法只是想往集合写入值,并且集合的类型范围希望是T及其父类,那么泛型可以定义为 ? super T 来表示

了解泛型的同学应该知道,super表示下界通配符,使用了下界通配符,只能写入值,不能取值,写入的值必须是T或者其子类

只能写入,不能取出就是消费者,有人可能有点理解了,我们来个更详细的解释,举个例子

我们还是沿用上面的例子,我们进行改造一下,苹果类有个addAll方法,传入一个苹果集合,将苹果对象放入这个集合里面

public class Apple extends Fruit{

    private Apple apple = new Apple();

    public void addAll(List<Apple> apples){
        apples.add(apple);
    }
}

现在需求变了,我们变更,我们想传入一个更大的水果集合,将苹果添加入水果集合里面,毕竟苹果是属于水果的子类,我们直接将水果集合传入进去,会编译报错,我们改造一下addAll方法,使用下界通配符将它的接收范围扩大,传入的集合范围是Apple或者其父类集合

public void addAll(List<? super Apple> apples){
    apples.add(apple);
}

有人会问了,这个下界通配符,跟CS有什么关系? 当然有,CSconsumer super的缩写,对于addAll方法来说,只要是将东西放进到入参内,那么入参就是消费者

CS也是针对方法来说的,如果某个方法的入参需要消费方法内的东西,入参并且是泛型的父类,那么使用下界通配符super

总结

如果进行简单的归纳,那就是

  • 只从方法入参集合获取值,那么使用 extends

  • 只从方法入参集合写入值,那么使用 super

感谢各位的阅读,以上就是“Java泛型的PE和CS原则说明”的内容了,经过本文的学习后,相信大家对Java泛型的PE和CS原则说明这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI