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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM