zoukankan      html  css  js  c++  java
  • java泛型-PECS

     1 package com.example.base;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import com.example.spring.MyLog;
     7 /**
     8  * Producer extends Consumer super  生产者使用extends,consumer使用super
     9  * 这里的生产者和消费者是相对容器而言的,
    10  *   生产者只能对外提供数据,不可以写入数据,数据来源于赋值操作(将参数化类型为子类的容器赋值过来)
    11  *   消费者表示只能向容器中写入数据,不能读取(只能以Object来接收)
    12  * 这里的extends和super指的是声明类型和参数化类型的关系,
    13  *    如下所示:等号左侧类型为声明类型,右侧为参数化类型
    14  *    List<? extends Number> intList = new ArrayList<Integer>();
    15  *    private List<? super Number> intList2 = new ArrayList<Number>();
    16  * @DESC 
    17  * @author guchuang
    18  *
    19  */
    20 public class PECS {
    21 
    22     int int1 = 1;
    23     long long1 = 11;
    24     Number number1 = 10;
    25     
    26     private List<Integer> intList = new ArrayList<Integer>();
    27     private List<Long> longList = new ArrayList<Long>();
    28     private List<Number> numberList = new ArrayList<Number>();
    29     
    30     public static void main(String[] args) {
    31         PECS pecs = new PECS();
    32         pecs.pe();
    33         pecs.cs();
    34     }
    35     
    36     /**
    37      * <? extends Number>  这种方式声明的泛型容器,不能写入任何类型的数据,只能读取数据
    38      * 其指定了上确界为Number,参数化类型(如:实际新建的容器类型T new ArrayList<T>())必须是Number的子类,所以读出的数据都可以上转型为Number
    39      * 理论含义是容器内包含的数据可能是Number的任何一种子类,所以无法添加数据。
    40      * 写数据的方式:
    41      *    声明一个具体类型(Number的子类型)的容器,向其中添加数据,将这个容器赋值给numbers容器
    42      * 优势:
    43      *    避免调用者向此容器内写入数据,只能读取里面的数据
    44      */
    45     public void pe() {
    46         //<? extends Number>  这种方式声明的泛型容器,不能写入任何类型的数据
    47         List<? extends Number> numbers = new ArrayList<Number>();
    48         //下面三种添加数据都会导致编译报错
    49         //foo.add(int1);
    50         //foo.add(long1);
    51         //foo.add(number1);
    52         
    53         //Number number = numbers.get(0);
    54         
    55         intList.add(123);
    56         intList.add(456);
    57         //将新创建的具有确定类型的容器(必须是Number的子类型)赋值给numbers,起到生产数据的目的
    58         numbers = intList;      //新容器的参数化类型是Integer,是Number的子类,所以可以赋值
    59         MyLog.info(numbers);
    60         Number number = numbers.get(0);    //读出来的类型依然是Number
    61         MyLog.info("read from ? extends Number: " + number);
    62         numbers = longList;
    63         numbers = numberList;
    64     }
    65     
    66     /**
    67      * Consumer super
    68      * ? super Number 表示容器中所有的数据类型都是Number或者Number的超类型,
    69      *  所以Number及其子类型(可以上转型为Number)可以写入,读取的时候由于不能确定类型,只能使用Object接收
    70      */
    71     public void cs() {
    72         List<? super Number> numbers = new ArrayList<Number>();
    73         numbers.add(int1);
    74         numbers.add(long1);
    75         numbers.add(number1);
    76         //numbers.add(new Object());    编译报错
    77         MyLog.info(numbers);
    78         
    79         //Number n = numbers.get(0);    编译报错
    80         Object n = numbers.get(0);      //只能以Object来接收数据
    81         //numbers = intList;    编译报错
    82         numbers = numberList;
    83         numbers = new ArrayList<Object>();
    84     }
    85 }
  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/gc65/p/11183659.html
Copyright © 2011-2022 走看看