java核心卷軸之泛型程序設計
本文根據《Java核心卷軸》第十二章總結而來,更加詳細的內容請查看《Java核心卷軸》
1. 泛型類型只能是引用類型,不可以使用基本數據類型。
2. 類型變量含義
E : 集合 K : 關鍵字 V : 值 T : 任意類型
3. 泛型類
3.1 註意事項
類型變量聲明放在類名的後面
3.2 示例
package com.BlueStarWei.generic; public class Pair<T> { private T first; private T second; publicPair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public void setFirst(T first) { this.first = first; } public T getSecond() { return second; } public void setSecond(T second) {this.second = second; } }
4. 泛型方法
4.1 註意事項
類型變量放在修飾符的後面,返回類型的前面
4.2 示例
package com.BlueStarWei.generic; public class GenericMethodDemo{ public static void main(String[] args) { String s = getMiddle("Hello","world","Happy"); System.out.println(s);//World } //T... 表示可以輸入任意個數的參數public static <T> T getMiddle(T... a){ return a[a.length / 2]; } }
5. 類型變量的限定<T extends BoundingType>
5.1 T應該是綁定類型的子類型。T和綁定類型可以是類,也可以是接口。
5.2 一個類型變量可以有多個限定;如: T extends Comparable & Serializable
5.3 示例
package com.BlueStarWei.generic; public class BoundingTypeDemo { public static void main(String[] args) { Integer[] a = new Integer[]{1,2,3,4}; int max = getMax(a); System.out.println(max); } public static <T extends Comparable<T>> T getMax(T[] a){ if(a == null || a.length == 0) return null; T max = a[0]; for (int i = 0; i < a.length; i++) { if(max.compareTo(a[i]) < 0){ max = a[i]; } } return max; } }
6. 運行時類型檢查只適用於原始類型
6.1 校驗情況
if(a instanceof Pair<String>) //編譯報錯 if(a instanceof Pair<T>) //編譯報錯 if(a instanceof Pair) //true
6.2 getClass返回的是原始類型
Pair<String> a = new Pair<String>("Hello", "World"); Pair<Integer> b = new Pair<Integer>(1,2); if(a.getClass().equals(b.getClass())){ System.out.println("true"); //class com.ebao.gs.pol.nb.test.Pair System.out.println(a.getClass()); }else{ System.out.println("false"); }
7. Java不支持泛型類型的數組
7.1 示例
Pair<String>[] as = new Pair<String>[10]; //編譯報錯
7.2 解決方案: 將參數化對象放入ArrayList
List<Pair<String>> list = new ArrayList<Pair<String>>();
8. 通配符的限定
8.1 子類型限定
8.1.1 Pair<? Extends Employee>不能調用setFirst方法,但是可以調用getFirst方法
? extends Employee getFirst() void setFirst(? extends Employee)
調用setFirst方法時,編譯器只知道需要某個Employee的子類型,但是不知道具體什麽類型。它拒絕傳遞任何特定類型(?不能用來匹配)。調用getFirst方法時,只是將getFirst的返回值賦值給一個Employee的引用,完全合法。
8.1.2 示例
public static void minMaxBonus(Manager[] manager, Pair<? extends Manager> result) { if(manager.length == 0 || manager == null) return; Manager minManager = manager[0]; Manager maxManager = manager[0]; for (int i = 0; i < manager.length; i++) { if(manager[i].getBonus() < minManager.getBonus()) minManager = manager[i]; if(manager[i].getBonus() > maxManager.getBonus()) maxManager = manager[i]; } result.setFirst(minManager);//編譯報錯 result.setSecond(maxManager);//編譯報錯 Manager m = (Manager)result.getFirst(); System.out.println(m.getBonus());
8.2 超類型限定
8.2.1 Pair<? super Manager>可以調用setFirst方法,但是調用getFirst方法會返回Object對象(可以類型強轉)
void setFirst(? super Manager) ? super Manager getFirst()
編譯器不知道setFirst方法的確切類型,但是可以用任意Manager對象(或子類型)調用它。然而,如果調用getFirst方法,返回的對象類型就得不到保證。只能把它賦值給一個Object(但是可以類型強制轉換)。
8.2.2 示例
public static void minMaxBonus(Manager[] manager, Pair<? super Manager> result) { if(manager.length == 0 || manager == null) return; Manager minManager = manager[0]; Manager maxManager = manager[0]; for (int i = 0; i < manager.length; i++) { if(manager[i].getBonus() < minManager.getBonus()) minManager = manager[i]; if(manager[i].getBonus() > maxManager.getBonus()) maxManager = manager[i]; } result.setFirst(minManager); result.setSecond(maxManager); Manager m = (Manager)result.getFirst(); System.out.println(m.getBonus()); }
8.3 總結
通常而言:帶有超類型限定的通配符可以向泛型對象中寫入,帶有子類型限定的通配符可以從泛型對象中讀取。
8.4 附表(Manager類)
package com.ebao.gs.pol.nb.test; public class Manager { private Long id; private String name; private Double bonus; public Manager(Long id, String name, Double bonus){ super(); this.id = id; this.name = name; this.bonus = bonus; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getBonus() { return bonus; } public void setBonus(Double bonus) { this.bonus = bonus; } }
9.泛型的意義
減少強制類型轉換的使用
更多內容,請關註:http://www.cnblogs.com/BlueStarWei/
java核心卷軸之泛型程序設計