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

Java 泛型完整進階指南:從基礎語法到通配符、邊界、嵌套與最佳實踐

     編輯:Java 相關知識

Java Generics 核心價值

JDK 5 引入泛型,提供編譯期型別安全、消除強制轉型、支援參數化類型。核心原理是型別擦除:執行期泛型資訊被擦除,僅保留原始類型(Raw Type)與必要的檢查轉型碼。

1. 基礎泛型類

public class Box<T> {
    private T value;
    public T get() { return value; }
    public void set(T value) { this.value = value; }
}

// 使用
Box<String> box = new Box<>();
box.set("hello");
String s = box.get(); // 無需轉型

2. 多型別參數

public class Pair<K, V> {
    private K key; private V value;
    public Pair(K k, V v) { key = k; value = v; }
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Pair<String, Integer> p = new Pair<>("age", 25);

3. 通配符 ? 與型別邊界

語法名稱含義典型用途
<?>無界通配符任意型別,相當於 <? extends Object>只讀操作、List<?> printAll(List<?> list)
<? extends T>上界通配符T 或 T 的子型別(協變)讀取集合元素、sum(List<? extends Number>)
<? super T>下界通配符T 或 T 的父型別(逆變)寫入集合元素、addAll(List<? super Integer>)

PECS 原則(Producer Extends, Consumer Super)

  • 若集合作為生產者(只讀取元素)→ 用 extends。
  • 若集合作為消費者(只寫入元素)→ 用 super。
  • 既讀又寫 → 不用通配符,用具體型別。
// 生產者:只讀
public double sum(List<? extends Number> list) { ... }

// 消費者:只寫
public void addIntegers(List<? super Integer> list) {
    list.add(1); // OK
    list.add(2); // OK
    // Number n = list.get(0); // 編譯錯誤,只能取 Object
}

4. 泛型方法

public class Util {
    // 單型別參數
    public static <T> void swap(T[] arr, int i, int j) {
        T tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
    }

    // 多型別參數
    public static <K, V> Map<K, V> newMap() {
        return new HashMap<>();
    }

    // 配合邊界
    public static <T extends Comparable<T>> T max(T a, T b) {
        return a.compareTo(b) > 0 ? a : b;
    }
}

5. 型別擦除的實際影響

  • 執行期 List 和 List 都是 List(Raw Type)。
  • 無法 new T()、T[] arr = new T[10]、instanceof T、靜態欄位共享。
  • 橋接方法:編譯器自動產生橋接方法保持多態。

6. 泛型與陣列

  • ❌ 不能建立具體泛型陣列:new List[10] 編譯錯誤。
  • ✅ 可建立通配符陣列:List<?>[] arr = new List<?>[10];
  • ✅ 可用 List<List<String>> 替代。
  • 可變參數 T... 實際是 T[],會產生「unchecked」警告,@SafeVarargs 抑制。

7. 泛型嵌套與遞迴型別界限

// 遞迴型別界限:Enum、Comparable 常見模式
public class Enum<E extends Enum<E>> { ... }
public interface Comparable<T> { int compareTo(T o); }

// 自定義 Builder 模式
public class Builder<T extends Builder<T>> {
    public T setName(String n) { ...; return (T) this; }
}

class PersonBuilder extends Builder<PersonBuilder> { ... }

8. 最佳實踐清單

  1. 盡量使用泛型,消除非受檢警告。
  2. 公開 API 必須泛型化,內部實作可用原始類型優化效能。
  3. 遵循 PECS 原則設計方法簽名。
  4. 避免泛型陣列,改用 List<E>。
  5. 文件化型別參數約束(如 <T extends Comparable<? super T>>)。
  6. 利用 @SafeVarargs 消除可變參數警告(確認安全時)。
  7. 考慮型別推斷(Diamond <>、Java 10 var)簡化代碼。

9. 進階範例:型別安全的異構容器

public class TypeSafeContainer {
    private Map<Class<?>, Object> map = new HashMap<>();

    public <T> void put(Class<T> type, T value) {
        map.put(type, value);
    }

    public <T> T get(Class<T> type) {
        return type.cast(map.get(type));
    }
}

// 使用
TypeSafeContainer c = new TypeSafeContainer();
c.put(String.class, "hello");
c.put(Integer.class, 42);
String s = c.get(String.class); // 型別安全
Integer i = c.get(Integer.class);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved