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

【Java每日一題】泛型擦除陷阱:List 與 List 的 Class 對象是否相等?

     編輯:Java 綜合教學

【Java每日一題】20161216 - 泛型擦除經典面試題

題目代碼

package Dec2016;
import java.util.ArrayList;
import java.util.List;

public class Ques1216 {
    public static void main(String[] args) {
        List<String> list01 = new ArrayList<String>();
        List<Integer> list02 = new ArrayList<Integer>();
        System.out.println(list01.getClass() == list02.getClass());
    }
}

問題

請問主程序輸出結果是什麼?

答案與解析

輸出結果:true

核心原因:泛型擦除

Java 泛型採用類型擦除機制,編譯器在編譯階段會將泛型類型參數擦除為其邊界類型(無界時為 Object)。運行時期,JVM 並不知道泛型的具體類型參數。

  • List<String> 和 List<Integer> 編譯後都變為原始類型 List
  • 兩個對象均為 ArrayList 實例,getClass() 返回同一個 Class<ArrayList> 對象
  • 因此 list01.getClass() == list02.getClass() 為 true

延伸思考

// 以下代碼編譯報錯,證明泛型信息在編譯期被擦除
List<String> list = new ArrayList<>();
// list.add(123); // 編譯錯誤:類型不匹配

// 但通過反射可繞過編譯期檢查
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list, 123); // 運行時成功添加 Integer 到 List<String>
System.out.println(list); // 輸出: [123]

關鍵點總結

  1. 泛型僅在編譯期生效,運行期類型信息被擦除
  2. 所有泛型實例共享同一個 Class 對象
  3. instanceof 不能用於泛型類型檢查(如 list instanceof List<String> 編譯錯誤)
  4. 這是 Java 與 C# 泛型(運行期保留類型信息)的本質區別

本題考察 Java 泛型核心機制,是高頻面試題,務必掌握「擦除法」原理及其帶來的限制與變通方案。

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