之前對JAVA一知半解時就拿起weiss的數據結構開始看,大部分數據結構實現都是采取通配符的思想,好處不言而喻。
首先建立兩個類employee和manager,繼承關系如下。其次Pair類是一個簡單的泛型類。
通配符的作用就是在泛型設計程序中允許類型參數變化
子類型限定
Pair<? extends Employee>
extends可以理解為是向下的 ↓
即所有Employee的子類都是可以的,可以理解為Pair<Manager>是Pair<? extends Employee>的子類型
1 /* 2 打印雇員對的方法 3 */ 4 public static void printBuddies(Pair<? extends Employee> p) 5 { 6 Employee first=p.getFirst(); 7 Employee second-p.getSecond(); 8 System.out.println(...) 9 }
上例的方法可以將Pair<Manager>傳遞過去
通配符限定還有個超類型限定
? super Manager
super關鍵字如同字面意思,是↑的,即所有Manager父類都是可以的。
1 /* 2 數組放入獎金最高和最低的經理 3 */ 4 public static void minmaxBonus(Manager[] a,Pair<? super Manager> result) 5 { 6 if(a.length==0) 7 return; 8 Manager min=a[0]; 9 Manager max=a[0]; 10 for(int i=0;i<a.length;i++) 11 { 12 if(min.getBonus()>a[i].getBonus()) 13 min=a[i]; 14 if(min.getBonus()<a[i].getBonus()) 15 max=a[i]; 16 } 17 result.setFirst(min); 18 result.setSecond(max); 19 }
直觀的講,帶有超類型限定的通配符可以向泛型對象寫入,帶有子類型限定的通配符可以從泛型對象讀取
下面定義一個類擴展了comparable接口
1 class getMax implements Comparable<Integer>{ 2 3 @Override 4 public int compareTo(Integer o) { 5 // TODO Auto-generated method stub 6 return 0; 7 } 8 9 }
可以觀察到Comparable接口本身就是一個泛型類型,實現后會重寫compareTo方法。
現在可以給出一個泛型max限定方法
public static <T extends Comparable> T max(..)
1 public class MyGenerics { 2 public static void main(String[] args) { 3 Integer[] nums=new Integer[]{10,8}; 4 System.out.println(max(nums)); 5 } 6 public static <T extends Comparable> T max(T[] a){ 7 if(a[0].compareTo(a[1])>0) 8 return a[0]; 9 else 10 return a[1]; 11 12 } 13 } 14 15 //output:10
但是compareTo方法下會標黃,提示
Type safety: The method compareTo(Object) belongs to the raw type Comparable.
References to generic type Comparable<T> should be parameterized
大意就是類型安全什么的,因為comparable接口已經是泛型接口comparable<T>限定了比較的類型
public static <T extends Comparable<T>> T max(..)
//所以最好采用這種形式
比較難理解的就是
public static <T extends Comparable<? super T>> T max(...)
與上文比較主要是有<T>與<? super T>的區別,文章的開頭已經清楚 ? super T 意思是所有T的超類都是可以的。
現在可以把T換成Manager類
public static <Manager extends Comparable<? super Manager>> Manager max(...)
如果沒有 ? super 的話,上面的方法只能對Manager類進行操作,但是有個超類型限定,Emoployee也可以使用這個方法。