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

Java 泛型完整指南:型別擦除、自訂類別/方法/介面、通配符與最佳實務

     編輯:更多程式設計知識

泛型核心價值

  1. 編譯期型別安全:將 ClassCastException 從執行期前移至編譯期。
  2. 消除強制轉型:List<String> list = ...; String s = list.get(0); 無需 (String)。
  3. 程式碼複用:同一演算法適用多種型別,如 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>) 編譯後簽名相同。改用不同方法名。

最佳實務清單

  1. API 設計優先使用泛型,避免原始型別。
  2. 集合宣告一律指定型別參數:List<User> users = new ArrayList<>(); (鑽石運算子 Java 7+)。
  3. 方法參數用 <? extends T> 讀取、<? super T> 寫入。
  4. 文件註解標註型別參數語意:@param <T> 元素型別,必須實作 Comparable。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved