假設需要編寫一個排序方法,能同時處理 Integer[]、Double[]、String[] 甚至任意類型陣列。若無泛型,必須為每種類型編寫重載方法,代碼嚴重冗餘。Java 泛型允許編寫單一泛型方法,透過類型參數化實現對多種類型的統一處理。
<E><E, T, K>)public class GenericTest {
// 泛型方法:列印任意類型陣列
public static <E> void printArray(E[] inputArray) {
for (E element : inputArray) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
Double[] doubleArray = {1.1, 2.2, 3.3, 4.4, 5.5};
Character[] charArray = {'H', 'E', 'L', 'L', 'O'};
// 此處不能傳入 int[]、double[]、char[] 基本類型陣列
printArray(intArray);
printArray(doubleArray);
printArray(charArray);
}
}
輸出結果:
1 2 3 4 5
1.1 2.2 3.3 4.4 5.5
H E L L O
有時需要限制傳入類型,例如只接受 Number 及其子類。使用 extends 關鍵字聲明上界:
public class MaximumTest {
// 比較三個值並返回最大值,要求 T 實作 Comparable<T>
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
T max = x; // 假設 x 為初始最大值
if (y.compareTo(max) > 0) max = y;
if (z.compareTo(max) > 0) max = z;
return max;
}
public static void main(String[] args) {
System.out.printf("%d, %d 和 %d 中最大的數為 %d%n%n", 3, 4, 5, maximum(3, 4, 5));
System.out.printf("%.1f, %.1f 和 %.1f 中最大的數為 %.1f%n%n", 6.6, 8.8, 7.7, maximum(6.6, 8.8, 7.7));
System.out.printf("%s, %s 和 %s 中最大的為 %s%n", "pear", "apple", "orange", maximum("pear", "apple", "orange"));
}
}
關鍵點:
<T extends Comparable<T>> 限定 T 必須實作 Comparable<T> 介面,確保可比較Integer、DoubleString 實作了 Comparable<String>,故可直接比較泛型類聲明與普通類相似,僅在類名後添加類型參數聲明部分。慣例使用單一大寫字母:T(Type)、E(Element)、K(Key)、V(Value)。
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<>(); // Java 7+ 鑽石語法
Box<String> stringBox = new Box<>();
integerBox.add(10);
stringBox.add("菜鳥教程");
System.out.printf("整型值為 :%d%n%n", integerBox.get());
System.out.printf("字符串為 :%s%n", stringBox.get());
}
}
| 概念 | 語法 | 說明 |
|---|---|---|
| 泛型方法 | <T> ReturnType method(T param) | 方法級別類型參數化 |
| 有界類型參數 | <T extends Bound> | 限制類型參數上界,支援多重界限 <T extends A & B> |
| 泛型類 | class Name<T> { ... } | 類級別類型參數化,實例化時具體化類型 |
| 類型推斷 | Box<> box = new Box<>(); | Java 7+ 鑽石語法,編譯器自動推斷類型參數 |
| 通配符 | >, <? extends T>, <? super T> | 表示未知類型、上界通配符、下界通配符 |
| 類型擦除 | 編譯時移除泛型資訊 | 運行時泛型資訊不存在,List<String> 與 List<Integer> 共用同一 Class 物件 |
new T() 編譯錯誤,需用反射或工廠模式List<Integer> 而非 List<int>)extends 用於讀取(生產者),super 用於寫入(消費者)—— PECS 原則