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 }