首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 泛型核心特性詳解:類型參數、通配符、邊界與類型擦除

     編輯:Java 相關知識

Java 泛型完整指南:從基礎語法到底層擦除機制

泛型是 Java SE 5 引入的編譯期類型安全機制,本質是參數化類型。掌握類型參數聲明、通配符邊界、類型擦除副作用,是寫出健壯庫代碼的關鍵。

基礎語法與命名慣例

  • 類型參數:單大寫字母 T (Type)、E (Element)、K (Key)、V (Value)、S (Subtype)
  • 聲明位置:類 ``、接口 ``、方法 ` void method(T t)`、構造器 ` Class(T t)`
  • 實例化:`new ArrayList()`、Java 10+ 支援鑽石操作符 `new ArrayList<>()`

邊界約束:extends 與 super

通配符:? extends T (生產者) vs ? super T (消費者)

PECS 原則:Producer Extends, Consumer Super

// 生產者:只讀取,用 extends
public void copyAll(List src, List dest) {
    for (Number n : src) dest.add(n); // 只能獲取 Number 或子類
}

// 消費者:只寫入,用 super
public void addIntegers(List list) {
    list.add(1);      // OK: Integer 是 Integer 子類
    list.add(new Object()); // 編譯錯誤: Object 不是 Integer 父類
}

// 無界通配符:List 相當於 List
// 只能讀取 Object,不能寫入 (除 null)

類型擦除:泛型的運行時真相

  • 編譯器擦除類型參數,替換為邊界 (默認 Object) 或第一個邊界
  • 運行時 `List` 和 `List` 都是 `List`
  • 橋接方法自動生成保證多態:`List.set(int, E)` -> `List.set(int, Object)`
// 擦除後等效代碼
public class Box {
    private T value;
    public void set(T value) { this.value = value; } // 擦除為 set(Object)
    public T get() { return value; }                  // 擦除為 Object get()
}

// 導致的限制:
// 1. 不能 new T()、不能 T[]、不能 instanceof T
// 2. 靜態字段/方法不能引用類型參數
// 3. 異常類不能泛型、catch 不能用類型參數

實戰陷阱與最佳實踐

1. 避免原始類型

List list = new ArrayList(); // 原始類型,失去類型檢查
List list = new ArrayList<>(); // 正確:參數化類型

2. 方法簽名優先通配符

// 差:泛型方法無實際類型關係
public  void print(List list) { ... }

// 好:通配符表達「任意元素列表」
public void print(List list) { ... }

3. 類型令牌模式繞過擦除

// 獲取運行時泛型類型
TypeToken> token = new TypeToken>() {};
Type type = token.getType(); // ParameterizedType: List

// 實現原理:匿名子類保留簽名信息
class TypeToken {
    final Type type;
    TypeToken() { type = getClass().getGenericSuperclass(); }
}

4. 可變參數堆污染

@SafeVarargs // 聲明開發者確保安全
public final  void addAll(List list, T... elements) { ... }

進階:聲明站點變異 vs 使用站點變異

Java 採用使用站點變異 (通配符),Kotlin/Scala 支援聲明站點變異 (`out`/`in`)。Java 中通配符雖繁瑣但更靈活,如同一方法參數既作生產者又作消費者時可用無界通配符或拆分方法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
語法含義典型場景
`>`上界:T 必須實現 Comparable排序算法、樹結構
``多重上界 (接口用 &)數值計算且可序列化
``下界:T 是 Integer 或其父類消費者模式、寫入操作