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

Java 泛型擦除導致「堆污染」卻不報錯的原理

     編輯:程式設計綜合問答

代碼現象


List lt1 = new ArrayList();
lt1.add("感冒靈");
List lt3 = lt1; // 未檢查轉換警告
System.out.println(lt3.get(0)); // 輸出 "感冒靈",無 ClassCastException

原理解析

  1. 泛型擦除:編譯後 ArrayList 變為原始類型 ArrayList,運行時無泛型信息。
  2. 未檢查轉換:List lt3 = lt1; 編譯器只給警告,運行時直接賦值成功,因兩邊都是 ArrayList。
  3. 延遲拋異常:從 lt3 取元素時,編譯器插入隱式強轉 (Integer) list.get(0),**此時才會拋 ClassCastException**。但示例中直接打印 Object(println(Object)),無強轉,**所以不報錯**。

驗證


Integer i = lt3.get(0); // 這行會拋 ClassCastException: String cannot be cast to Integer

最佳實踐

  • 編譯器警告 Unchecked conversion 必須修復,加 @SuppressWarnings("unchecked") 只在確認安全處使用。
  • 避免原始類型與泛型混用,全程使用參數化類型。
  • JDK 8+ 可用 List lt1 = new ArrayList<>(); 鑽石語法減少冗余。

參考:堆污染詳解

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