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

Java 泛型深度解析:從類型擦除到通配符上下界的完整指南

     編輯:Java 相關知識

一、為什麼需要泛型?

無泛型時,集合只能存 Object,取出需強轉,編譯期無法發現類型錯誤,運行期拋 ClassCastException:

List list = new ArrayList();
list.add("hello");
list.add(100); // 編譯通過
String s = (String) list.get(1); // 運行拋 ClassCastException

二、什麼是泛型?

參數化類型。將類型由具體類型參數化(如方法形參),使用時傳入具體類型實參:

List<String> list = new ArrayList<>();
list.add("hello");
// list.add(100); // 編譯報錯
String s = list.get(0); // 無需強轉

源碼層面:interface List<E> { E get(int index); },E 為類型形參,實例化時替換為實參。

三、自定義泛型類/接口/方法

// 泛型類
class Box<T> {
    private T data;
    public Box(T data) { this.data = data; }
    public T getData() { return data; }
}

// 泛型方法(非泛型類中也可定義)
public static <T> void print(T t) { System.out.println(t); }

四、類型擦除:泛型只在編譯期存在

Box<String> b1 = new Box<>("a");
Box<Integer> b2 = new Box<>(1);
System.out.println(b1.getClass() == b2.getClass()); // true,都是 Box.class

編譯器擦除泛型信息,運行期只有原始類型。因此無法創建泛型數組:new T[10] 非法。

五、通配符 ? 与上下界

1. 無界通配符 Box<?>

表示任意 Box<X> 的父類,可讀不可寫(除 null):

void printBox(Box<?> box) { System.out.println(box.getData()); }

2. 上界 <? extends Number>

只能傳入 Number 及其子類(Integer, Double...),只能讀,不能寫(因不確定具體子類型):

void process(Box<? extends Number> box) {
    Number n = box.getData(); // OK
    // box.setData(1); // 編譯錯誤
}

3. 下界 <? super Integer>

只能傳入 Integer 及其父類(Number, Object),可寫,讀出只能是 Object:

void addInt(Box<? super Integer> box) {
    box.setData(10); // OK
    Object o = box.getData(); // 只能作為 Object 讀
}

六、PECS 原則速記

Producer Extends, Consumer Super
作為生產者(只讀)用 extends;作為消費者(只寫)用 super。

七、最佳實踐清單

  1. 集合聲明盡量使用接口類型:List<String> list = new ArrayList<>();
  2. 方法參數優先用通配符提高靈活性:void copy(List<? extends T> src, List<? super T> dest)
  3. 避免在泛型類中使用 static 字段引用類型參數(會被所有實例共享)。
  4. 不可創建泛型數組,改用 List<T> 或 T[] toArray(T[] a)。
  5. 編寫泛型方法時,若類型參數僅出現一次,可替換為 ?。

八、參考資源

  • 《Effective Java》第 5 章:泛型
  • JDK 集合框架源碼(ArrayList, HashMap, Collections)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved