ClassCastException 從執行期前移至編譯期。List<String> list = ...; String s = list.get(0); 無需 (String)。Collections.sort、DAO<T>。Java 泛型資訊僅存在於**原始碼與編譯期**,編譯後 class 檔中不保留實際型別參數:
List<String>、List<Integer> 編譯後皆為 List (原始型別)。checkcast 指令,執行期仍為 Object 操作。new T()、T[] arr = new T[10]、instanceof T、靜態欄位/方法參考 T。public class Box<T> {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
}
// 使用
Box<String> box = new Box<>();
box.set("Hello");
String s = box.get(); // 型別安全
public class Util {
// 方法獨立型別參數
public static <T> void print(T t) { System.out.println(t); }
// 限定上界
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
}
// 呼叫
Util.print("Hello"); // 推斷 T=String
Util.<Integer>print(123); // 顯式指定
Util.max(3, 5); // T=Integer
public interface Processor<T> { void process(T t); }
// 實作指定型別
class StringProcessor implements Processor<String> {
public void process(String s) { System.out.println("Str: " + s); }
}
// 實作保留泛型
class GenericProcessor<T> implements Processor<T> {
public void process(T t) { System.out.println("Gen: " + t); }
}
| 語法 | 含義 | 適用場景 |
|---|---|---|
<?> | 未知型別,唯讀視為 Object | 只讀取元素、呼叫 Object 方法 |
<? extends T> | 上界:T 或其子類,**生產者** (Producer) | 從集合讀取 T 及子類物件 (不可寫入) |
<? super T> | 下界:T 或其父類,**消費者** (Consumer) | 向集合寫入 T 及子類物件 (讀取只得 Object) |
PECS 原則:**Producer Extends, Consumer Super**。
List<String>[] arr = new List<String>[10]; 編譯錯誤。改用 List<List<String>>。static T field;、static void method(T t) 錯誤。改用泛型方法 static <T> void method(T t)。void m(List<String>)、void m(List<Integer>) 編譯後簽名相同。改用不同方法名。List<User> users = new ArrayList<>(); (鑽石運算子 Java 7+)。<? extends T> 讀取、<? super T> 寫入。@param <T> 元素型別,必須實作 Comparable。