前言:
“大道若簡,萬物歸一”。
-
為什么泛型?
Java中的泛型是由單詞“Generic”翻譯過來的,“Generic”即表示“一般、通用”的意思。而sun在JDK1.5之后引入的泛型的目的就在於此,將“特殊的,專屬的”類型參數化。
-
泛型的優點:
1)讓泛型類和泛型方法具備可重用性;
2)在編譯時而非運行時提前報錯,實現類型安全。
-
定義泛型類
1 package com.gdufe.thread.generic; 2 3 import java.util.ArrayList; 4 5 /* 6 * 基於數組鏈表構造泛型類型的棧(stack) 7 */ 8 public class GenericStack<T>{ 9 10 ArrayList<T> list = new ArrayList<T>(); 11 12 public int getSize(){ 13 return list.size(); 14 } 15 public T get(int index){ 16 return list.get(index); 17 } 18 public T peek(){ 19 return list.get(getSize()-1); 20 } 21 public void push(T t){ 22 list.add(t); 23 } 24 public boolean isEmpty(){ 25 return list.size()==0; 26 } 27 public T pop(){ 28 T t = list.get(getSize()-1); 29 list.remove(getSize()-1); 30 return t; 31 } 32 }
泛型類測試1:
1 package com.gdufe.thread.generic; 2 3 public class Demo1 { 4 5 public static void main(String[] args) { 6 GenericStack<Integer> stack = new GenericStack<Integer>(); 7 stack.push(1); 8 stack.push(3); 9 stack.push(2); 10 System.out.println(stack.list); 11 } 12 13 }
輸出結果:
[1, 3, 2]
假如例子中沒有按照統一的“Integer”類型,編譯報錯!
-
泛型方法
1 package com.gdufe.thread.generic; 2 3 public class Demo2 { 4 public static void main(String[] args) { 5 Integer[] integer = new Integer[]{1,2,3}; 6 String[] string = new String[]{"Jack","John","Tom"}; 7 Demo2.print(integer); 8 Demo2.print(string); 9 } 10 //泛型方法:打印數組中的每一個元素 11 public static <E> void print(E[] array){ 12 for(E t:array){ 13 System.out.println(t); 14 } 15 } 16 }
輸出結果:
1 2 3 Jack John Tom
1)定義泛型方法時,除了在參數里面需要指明泛型的類型之外,方法本身也應該指明泛型的類型
2)外界訪問泛型方法,一般通過“類.<泛型類型>方法”進行調用,其中的<泛型類型>可省略。
-
通配泛型 (受限|非受限)
-
1 package com.gdufe.thread.generic; 2 3 4 public class Demo3 { 5 public static void main(String[] args) { 6 7 GenericStack<Integer> stack1 = new GenericStack<Integer>(); 8 stack1.push(1); 9 stack1.push(12); 10 stack1.push(123); 11 Demo3.print(stack1); 12 13 } 14 //受限制的通配,調用時‘?’必須是Number子類型,否則編譯報錯 15 public static void print(GenericStack<? extends Number> stack){ 16 for(int i=0;i<stack.getSize();i++){ 17 System.out.println(stack.get(i)); 18 } 19 } 20 }
輸出結果:
1 12 123
1 package com.gdufe.thread.generic; 2 3 4 public class Demo4 { 5 public static void main(String[] args) { 6 GenericStack<Integer> stack1 = new GenericStack<Integer>(); 7 stack1.push(1); 8 stack1.push(12); 9 stack1.push(123); 10 11 //stack2中元素默認是‘Object’類型 12 GenericStack stack2 = new GenericStack(); 13 stack2.push("Jack"); //String類型 14 stack2.push("Ammy"); 15 stack2.push(1.1); //Double類型 16 17 Demo4.add(stack1, stack2); 18 19 while(!stack2.isEmpty()){ 20 System.out.println(stack2.pop()); 21 } 22 } 23 //泛型方法:把stack1里面的元素壓入到stack2中,其中stack2中的元素類型應“>=”stack1中元素類型,否則編譯報錯 24 public static <T> void add(GenericStack<T> stack1,GenericStack<? super T> stack2){ 25 while(!stack1.isEmpty()){ 26 stack2.push(stack1.pop()); 27 } 28 } 29 }
輸出結果:
1
12
123
1.1
Ammy
Jack
--------------------------------
注意事項:
1)泛型僅存在於編譯時,程序運行之前所有泛型已被自動轉化
2)不能使用泛型直接創建實例 ,比如:T t = new T;
3) 不能使用泛型直接創建數組 ,比如:T[] t = new T[N];