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

Java 泛型類型擦除機制詳解:編譯時擦除、通配符上下界、數組實化與泛型差異

     編輯:Java 綜合教學

Java 泛型類型擦除機制詳解

泛型是 JDK 5 引入的編譯期類型安全機制,**運行期類型資訊被擦除**,這是許多困惑的根源。

常見錯誤:List<String> 非 List<Object> 子型別

public static void accept(ArrayList<Object> al) { /* ... */ }
public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    list.add("a");
    accept(list); // 編譯錯誤!List<String> 不能傳給 List<Object>
}

原因:編譯後兩者皆擦除為 ArrayList,但編譯器檢測到泛型參數不兼容而報錯。

通配符與有界通配符

  • List<?>:未知類型,只能讀取為 Object,**不能添加**元素 (除 null)。
  • List<? extends Number>:上界通配符,代表 Number 或其子類,**只能讀**,不可寫 (協變)。
  • List<? super Number>:下界通配符,代表 Number 或其父類,**可寫入 Number 及子類**,讀取只能作為 Object (逆變)。
public static void test(List<?> list) {
    for (Object o : list) System.out.println(o);
    // list.add(new Object()); // 編譯錯誤
}

泛型與數組差異

特性泛型數組
類型資訊編譯期擦除 (非具體化)運行期保留 (具體化)
協變性不變協變
存儲檢查編譯期運行期 (ArrayStoreException)
Object[] objs = new String[10]; // 合法
objs[0] = new Integer(1);       // 運行期拋出 ArrayStoreException

List<Object> list = new ArrayList<String>(); // 編譯錯誤

實際建議

  • 優先使用泛型,享受編譯期類型安全。
  • API 設計時善用 ? extends T (生產者) 與 ? super T (消費者) —— **PECS 原則**。
  • 避免泛型數組建立 (new List<String>[10] 非法),改用 List<List<String>>。

譯文參考:Java Type Erasure Mechanism Example

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