Java泛型中的PECS原则
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java泛型中的PECS原则相关的知识,希望对你有一定的参考价值。
文章目录
PECS描述:
PECS原则的全拼是"Producer Extends Consumer Super"。
当需要频繁取值,而不需要写值则使用" ? extends T “作为数据结构泛型。相反,当需要频繁写值,而不需要取值则使用” ? super T "作为数据结构泛型。
例如:
List<? extends T>
,你可以把这个List当成是一个生产者,可以从里面拿东西但是不能从里面放东西。也就是PE 只读。
List<? super T>
,可以把这个List当成一个消费者,你可以往里面存数据,但是不能往里面获取数据。也就是SC 只写。
代码案例
package com.test;
import java.util.*;
/**
* 定义三个父子类: Fruit -> Apple -> RedApple
*/
class Fruit
class Apple extends Fruit
class RedApple extends Apple
class Main
/**
* 代码验证
* @param args
*/
public static void main(String[] args)
/**
* 1. List<? extends Apple> 必须使用 Apple的子类型List
* 2. add()方法编译报错
* 3. get()方法编译通过
*
* 理解: List<? extends Apple> 作为存储源可以确定上界但不能确定下界, [未知,Apple],因此,在进行元素添加的时候无法确定是Apple或者
* Apple的哪一个子类, 因此, 无法进行自动转型,不能 add();
*
* 但是再获取数据的时候, 能够明确数据肯定是 Apple或者 Apple的子类类型 [NULL, Apple], 因此,使用Apple进行接收即可, 可以 get()。
*
* 总结: PE (producer extends) 生产者使用 extends, 读多写少(生产者读取了才能进行生产)
*/
//List<? extends Apple> apples = new ArrayList<Fruit>(); 编译报错
//List<? extends Apple> apples = new ArrayList<Apple>(); 正确
List<? extends Apple> apples = new ArrayList<RedApple>(); //正确
apples.add(null); //正确
apples.add(new Fruit()); //编译报错
apples.add(new Apple()); //编译报错
apples.add(new RedApple()); //编译报错
//Fruit apple = apples.get(0); //正确
Apple apple = apples.get(0); //正确
/**
* 1. List<? super Apple> 必须使用 Apple的父类型List
* 2. add()方法编译通过
* 3. get()方法编译通过
*
* 理解: List<? super Apple> 作为存储源可以确定下界但不能确定上界, [Apple,Object/未知],因此,在进行元素添加的时候可以添加Apple或者Apple的子类类型,因为数据存储源最小也是Apple类型,Apple和Apple的子类型可以自动向上转型为Apple和Apple的父类型; 但是再获取数据的时候, 就不能判断类型了,只能由Object最强顶级父类型来接收,因为存储的数据存储的范围为[NULL,Apple+]。
* 因此,使用Apple进行接收即可, 可以 get()。
*
* 总结: CS (customer super) 消费使用 super, 写多读少(消费者消费了要进行写入)
*/
//List<? extends Apple> apples2 = new ArrayList<Fruit>(); 编译报错
//List<? extends Apple> apples2 = new ArrayList<Apple>(); 正确
List<? super Apple> apples2 = new ArrayList<Fruit>(); //正确
apples2.add(new RedApple()); //正确
apples2.add(new Apple()); //正确
//apples2.add(new Fruit()); 编译错误
//Apple apple2 = apples2.get(0); //错误
//Fruit apple2 = apples2.get(0); //错误
Object apple2 = apples2.get(0); //正确
apples2.get(1);
总结:
PE (producer extends) 生产者使用 extends, 上界确定,读取优良(用Apple接收),下界不定,写入不行(只能存null),读多写少(生产者读取了才能进行生产)
CS (customer super) 消费使用 super, 上界不定,读取不行(只能用Object接收),下界确定,写入优良(可以写入Apple与Apple的子类型),写多读少(消费者消费了要进行写入)
以上是关于Java泛型中的PECS原则的主要内容,如果未能解决你的问题,请参考以下文章