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

Java 泛型實戰技巧:方法泛型、通配符、類型擦除與陷阱全解析

     編輯:Java 相關知識

基礎語法:方法級泛型

<K, V> void put(K key, V value) { ... }

類似 C++ 模板,但 泛型實際類型必須為引用型別(不可用 int 等基本型別)。

常見誤區:泛型無法直接運算

<T> T add(T a, T b) {
    // return a + b; // 編譯錯誤!T 不保證有 + 運算子
    return null;    // 只能回傳 null 或參數本身
}

回傳型別推導為參數共同父類(如 Integer + String → Object)。

實用技巧集錦

1. 陣列元素交換(泛型方法)

public static <T> void swap(T[] arr, int i, int j) {
    T tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
// 正確:swap(new Integer[]{1,2,3}, 0, 1);
// 錯誤:swap(new int[]{1,2,3}, 0, 1); // 基本型別陣列不適用

2. 型別邊界:extends / super

<T extends Number> void process(T t) { ... }  // T 必須是 Number 或其子類
<T super Integer> void consume(T t) { ... }   // T 必須是 Integer 或其父類(僅用於通配符)

3. 自動型別轉換工具

public static <T> T autoConvert(Object obj) {
    return (T) obj; // 編譯器會根據賦值目標推導 T
}
Object obj = "hello";
String s = autoConvert(obj); // T 推導為 String,無需強轉

4. 陣列填充(忽略型別檢查)

public static <T> void fillArray(T[] arr, T val) {
    for (int i = 0; i < arr.length; i++) arr[i] = val;
}
Integer[] nums = new Integer[3];
fillArray(nums, 99); // 正常
fillArray(nums, "oops"); // 編譯錯誤:String 不能賦值給 Integer[]

5. 集合遍歷:泛型 vs 通配符

<T> void showAndAdd(Collection<T> col, T item) {
    col.add(item);          // 允許新增
    for (T e : col) System.out.println(e);
}

void showOnly(Collection<?> col) {
    // col.add(item);      // 編譯錯誤:未知型別不可新增
    for (Object e : col) System.out.println(e);
}

核心差異:通配符 ?> 代表「未知具體型別」,為安全禁止寫入;泛型 <T> 保留型別資訊,允許寫入。

6. 類級泛型

class Box<E> {
    private E data;
    public void set(E e) { data = e; }
    public E get() { return data; }
}

類型擦除:核心真相

  • 泛型資訊 僅存在編譯期,執行期被擦除為原始型別(List<Integer> → List)
  • Vector<Integer> 與 Vector<String> 共用同一份 .class 位元碼
  • 重載陷阱:以下兩方法擦除後簽名相同,不能共存
void show(Vector<Integer> v) {}
void show(Vector<String> v) {} // 編譯錯誤:擦除後重複

建議與最佳實踐

  1. 優先使用集合(List<T>)而非泛型陣列
  2. API 設計盡量用泛型方法/類,減少強制轉型
  3. 需執行期型別時,傳遞 Class<T> 型別權杖(如 Array.newInstance(clazz, size))
  4. 通配符 ? extends T 用於「讀取」(生產者),? super T 用於「寫入」(消費者)— PECS 原則
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved