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

JDK 5.0 Generics 泛型核心語法與通配符實戰

     編輯:關於JSP

Generics 是 JDK 5.0 最重要的特性之一,旨在解決集合框架中的類型安全與強制轉型問題。本文通過完整代碼範例,系統講解基本用法、通配符(?)、上下界通配符、泛型方法三大核心語法,並對比 C++ 模板差異。

基本用法:類型參數化


// JDK 1.4 風險寫法
List list = new LinkedList();
list.add(new Integer(0));
Integer x = (Integer) list.iterator().next(); // 需強轉,運行時才發現類型錯誤

// JDK 5.0 泛型寫法
List<Integer> list = new LinkedList<Integer>();
list.add(new Integer(0));
Integer x = list.iterator().next(); // 編譯期保證類型安全,無需強轉

泛型資訊僅存在編譯期(類型擦除),運行期實際為原始類型。但編譯器插入隱式轉型與檢查,消除了 ClassCastException 風險。

通配符 ?:未知類型的靈活處理

無界通配符 Collection<?>

表示「某種具體類型的集合,但類型未知」。

  • 讀取安全:元素視為 Object,for (Object e : c) 安全。
  • 寫入受限:c.add(new Object()) 編譯錯誤(除 null),因無法確認類型相容。但可調用 get() 讀取。
public void printAll(Collection<?> c) {
    for (Object e : c) System.out.println(e);
}

上界通配符 <? extends Shape>

表示「Shape 或其子類型」。

  • 讀取:元素視為 Shape,可安全調用 draw()。
  • 寫入禁止:shapes.add(new Rectangle()) 錯誤,因集合實際可能是 List<Circle>,加入 Rectangle 違反類型契約。
public void drawAll(List<? extends Shape> shapes) {
    for (Shape s : shapes) s.draw();
    // shapes.add(new Rectangle()); // 編譯錯誤
}

下界通配符 <? super Circle>

表示「Circle 或其父類型」。

  • 寫入安全:可加入 Circle 或其子類。
  • 讀取僅得 Object:因實際類型可能是 Object 或 Shape。

PECS 原則:Producer Extends, Consumer Super。頻繁讀取用 extends,頻繁寫入用 super。

泛型方法

方法簽名帶類型參數,調用時自動推斷或顯式指定:

public static <T> void copy(List<T> src, List<T> dest) { ... }
// 調用
copy(intList, objList); // T 推斷為 Integer? 實際需兼容性檢查
copy(intList, intList); // OK

泛型方法配合通配符,能寫出極具復用性的工具方法(如 Collections.sort、Collections.copy)。

與 C++ 模板的關鍵差異

  1. 類型擦除 vs 代碼膨脹:Java 編譯期擦除泛型資訊,單一字節碼服務所有類型;C++ 編譯期為每種具體類型生成獨立代碼。
  2. 基本類型支援:Java 泛型僅支援引用類型(基本類型需裝箱);C++ 模板支援任意類型。
  3. 運行期類型資訊:Java 運行期無法獲取泛型參數(List<Integer>.class == List<String>.class);C++ 可通過模板特化實現類型相關邏輯。

實戰建議

  • 集合聲明、API 參數、返回值**盡量使用泛型**,消除非受檢轉型警告。
  • 靈活運用 ? extends/? super 設計寬容度高的 API(如 addAll(Collection<? extends E>))。
  • 避免在泛型代碼中使用 instanceof 檢查泛型參數(擦除後無效),改用類型令牌或工廠模式。
  • 注意泛型與陣列不兼容:new List<String>[10] 非法,改用 List<List<String>>。

泛型是 Java 類型系統的重大增強,掌握其語法精髓與通配符邏輯,能寫出更安全、自文檔化、可復用的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved