所謂泛型,就是在定義類、接口、方法、參數或成員變量的時候,指定它們操作對象的類型為通用類型。
使用 尖括號 <> 操作符 (The diamond operator )表示泛型, 尖括號內可以放置大寫字母 (代表一個未知類型) 或問號 ? (代表若干個類型)作為參數。比如,習慣上選擇以下字母代表某種類型:
- T 意味某種類型
- E 意味 鏈表、數組里的元素,如List<E> list 表示 list 里的元素。
- K意味map(k,v) 里的鍵值 Key
- V 意味 返回或映射的值。
然而,泛型的運用要受到如下限制 :
- 不能使用基本類型的類型參數,可以使用其包裝類型代替。
- 靜態成員無法使用類型參數。
- 不能使用泛型類異常
- 不能實例化泛型對象或數組,如:
T t = new T(); T[] a=new T;
5,. 不能使用泛型數組,如:
import java.util.*; public class Test{ public static void main(String args[]){ List<String> arr[] = new ArrayList<String>[5]; } }
D:\java\test\OS_China\generic>javac Test.java
Test.java:5: 錯誤: 創建泛型數組 List<String> arr[] = new ArrayList<String>[5]; ^ 1 個錯誤
至於代表若干類的,放在尖括號內的 通配符 ?:<?>,還分 上限通配符 (Upper Bounded Wildcards) 和 下限通配符 (Lower Bounded Wildcards)。
論點:
上限通配符 <? extends U> 可以代表這個未知類型 U,或者 通過關鍵字 extends 所能想象出的 U 類的任何一個子類。同樣,下限通配符 <? super L> 可以代表這個未知類型 L,或者 通過關鍵字 super 所能想象出的 L類的任何一個超類。
這里分別以多個接口 interface 和 多個類 class 為基礎, 創建 繼承關系。
並以通過編譯的代碼, 證明以上論點成立。
/* <? super T> 與 <? extends T> 的區別, * T 代表一個給定的接口 * */ import java.util.*; interface A1{} interface A2{} interface A3{} interface A4{} interface B1 extends A1{} interface B2 extends A1,A2{} interface B3 extends A3,A4{} interface B4 extends A4{} interface C1 extends B2{} interface C2 extends B2,B3{} interface C3 extends B3{} interface D1 extends C1,C2{} interface D2 extends C2{} interface E1 extends D1{} interface E2 extends D1{} interface E3 extends D2{} interface E4 extends D2{} public class UP_Interface { public static void main(String args[]){ /******************************************** * 此處 extends 表示 有上界的統配符 ?,上界為 C2 * 由此定義的引用 listUpper可以作為 * 接下來的 7 種 子泛型類型的 ArrayList 的引用來使用。 **********************************************/ List<? extends C2> listUpper;//上界統配符 ?, 上界為 C2 listUpper=new ArrayList<C2>();//能存儲 C2 D1 D2 E1 E2 E3 E4 listUpper=new ArrayList<D1>();//能存儲 D1 E1 E2 listUpper=new ArrayList<D2>();//能存儲 D2 E3 E4 listUpper=new ArrayList<E1>();//能存儲 E1 listUpper=new ArrayList<E2>();//能存儲 E2 listUpper=new ArrayList<E3>();//能存儲 E3 listUpper=new ArrayList<E4>();//能存儲 E4 /************************************************* * super 表示有下界的統配符 ? ,下界為 C2 , * 由此定義的引用 listLower 可以作為 * 接下來的 7 種 子泛型類型的 ArrayList 的引用來使用。 ***************************************************/ List<? super C2> listLower; listLower=new ArrayList<A1>(); //能存儲 A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<A2>(); //能存儲 A2 B2 C1 C2 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<A3>(); //能存儲 A3 B3 C2 C3 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<A4>(); //能存儲 A4 B3 B4 C2 C3 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<B2>(); //能存儲 B2 C1 C2 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<B3>(); //能存儲 B3 C2 C3 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<C2>();// 能存儲 C2 D1 D2 E1 E2 E3 E4 } }
/* <? super T> 與 <? extends T> 的區別, * T 代表一個給定的類 * */ import java.util.*; class A1{} class A2{} class A3{} class A4{} class B1 extends A1{} class B2 extends A1{} class B3 extends A3{} class B4 extends A4{} class C1 extends B2{} class C2 extends B2{} class C3 extends B3{} class D1 extends C1{} class D2 extends C2{} class E1 extends D1{} class E2 extends D1{} class E3 extends D2{} class E4 extends D2{} public class UP_Class{ public static void main(String args[]){ /******************************************** * 此處 extends 表示 有上界的統配符 ?,上界為 C2 * 由此定義的引用 listUpper可以作為 * 接下來的 7 種 子泛型類型的 ArrayList 的引用來使用。 **********************************************/ List<? extends C2> listUpper;//統配符 ? 的上界為 C2 listUpper=new ArrayList<C2>();//能存儲 C2 D2 E3 E4 listUpper=new ArrayList<D2>();//能存儲 D2 E3 E4 listUpper=new ArrayList<E3>(); listUpper=new ArrayList<E4>(); /************************************************* * super 表示有下界的統配符 ? ,下界為 C2 , * 由此定義的引用 listLower 可以作為 * 接下來的 7 種 子泛型類型的 ArrayList 的引用來使用。 ***************************************************/ List<? super C2> listLower; listLower=new ArrayList<A1>(); //能存儲 A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<B2>(); //能存儲 B2 C1 C2 D1 D2 E1 E2 E3 E4 listLower=new ArrayList<C2>();// 能存儲 D2 E3 E4 } }