標籤:ati integer 基本類型 tor 父類 情況 return 種類 extend
1.泛型的概念
Java中我們說的泛型指的泛化的類型,如在定義iterator方法時 <E> 就是指的泛型,在實際聲明時可以用特定的參考型別替代<>中的字母,如
ArrayList<String> arrString = new ArrayList<>();
該語句實現了指向String對象的 ArrayList容器的聲明。
2.泛型的作用
在使用容器時,為了免於類型轉化的麻煩,在定義容器時加上泛型並制定參考型別可以確保型別安全,同時動態綁定時無需做顯式類型轉換。
3. 泛型的自訂
在自訂泛型時,泛型的<>放在類型後面,括弧中可以用單個字母表示(E:element , T:Type , K:key , V:value)
1 public class Student <T>{ 2 private T grade; 3 4 public Student(T grade){ 5 this.grade = grade; 6 } 7 public Student(){ 8 } 9 10 public T getGrade() {11 return grade;12 }13 14 public void setGrade(T grade) {15 this.grade = grade;16 }17 }
在定義和使用泛型時需要注意:① 泛型不能運用在靜態屬性上 ② 使用泛型時,實現的類型不能是基本類型而必須是參考型別。類似的泛型還可以用來定義介面和方法。
4.泛型的繼承
泛型的繼承滿足: ① 若保留父類泛型 則 子類為泛型子類 ② 若不保留父類泛型 則子類按需要實現即可
1 class Father<T1,T2>{ 2 3 } 4 // 父類泛型全部保留,子類也需要全部保留,子類泛型個數 >= 父類 5 class C1<T1,T2,A,B> extends Father<T1,T2>{ 6 } 7 // 父類泛型部分保留,子類也要保留父類中現有泛型,此外子類可以根據自己的需要增加其他類型 8 class C2<A,T2,B> extends Father<Integer,T2>{ 9 }10 // 父類泛型為具體類型,子類可以根據自己需要來使用泛型(可以不使用)11 class C3<A> extends Father<Integer,String>{12 }13 // 父類為非泛型類,子類可以是也可以不是泛型類14 class C4<A,B>extends Father{15 }
5.泛型的擦除
泛型的擦除指的在使用/繼承/實現 時沒有指定類型,預設泛型的實際類型類似與Object,但不等同與Object 如:
1 ArrayList arrayList = new ArrayList(); //類似於下一行2 // ArrayList<Object> arrayList = new ArrayList<>();
6.泛型的萬用字元及上下限
當<T>中可以實現的不止一種類型時,我們可以採用<?>來代表 Object或者Object的所有子類。此外通過採用 extends 和 super兩個
關鍵字,可以將類型指定在某個範圍內。如
1 public static void main(String[] args) { 2 3 List<? extends Fruit> list1 = new ArrayList<Apple>(); 4 test(list1); 5 List<? extends Apple> list2 = new ArrayList<Apple>(); 6 test(list2); 7 List<? extends Apple> list3 = new ArrayList<FujiApple>(); 8 test(list3); 9 List<?> list4 = new ArrayList<Apple>();10 // test(list4); // List<?> list4 相當於 List<? extends Object> list4 因此11 // 當List<? extends Fruit> 類型的形參只能接收Fruit類或者它的子類作為參數12 }13 14 public static void test(List<? extends Fruit> list){15 // list.add(new Apple()); //這裡無法添加是因為list有可能是Apple的子類的容器,子類的容器無法儲存父類的引用16 list.add(null);17 }
上例中滿足 Apple,Banana類為Fruit的子類 ,FujiApple為Apple的子類。 當test方法的參數為List<? extends Fruit>類型的容器時,list4無法作為實參傳入
因為Object 為Fruit類的父類。
1 public static void main(String[] args) { 2 List<? super Apple> list5 = new ArrayList<Apple>(); 3 test1(list5); 4 List<? super FujiApple> list6 = new ArrayList<Apple>(); 5 // test1(list6); // List<? super FujiApple> 類型的範圍超過了List<? super Apple>因此無法調用 6 List<? super Apple> list7 = new ArrayList<Fruit>(); 7 test1(list7); 8 List<? super Apple> list8 = new ArrayList<Object>(); 9 test1(list8); 10 }11 12 public static void test1(List<? super Apple> list){13 list.add(new FujiApple());14 list.add(new Apple());15 // list.add(new Fruit()); //這裡Fruit類型為Apple的父類,容器list在確保安全的情況下最高只能添加Apple類的對象16 list.add(null);17 }
類似的 <? super Apple> 類型的容器的物件類型不能超過Apple類型(不能是Apple類型的父類),而作為實參 傳入test1的類型的範圍不能大於<? super Apple>的範圍。
list6由於泛型型別的範圍超過了 test1的形參範圍,因而編譯器報錯。
Java中的泛型