1. 程式人生 > >基礎知識-Java泛型擦除(簡潔明瞭)

基礎知識-Java泛型擦除(簡潔明瞭)

0.概念

    Java 泛型的引數只可以代表類,不能代表個別物件。由於 Java 泛型的型別引數之實際型別在編譯時會被消除,所以無法在執行時得知其型別引數的型別。Java 編譯器在編譯泛型時會自動加入型別轉換的編碼,故執行速度不會因為使用泛型而加快。

---百度百科

    泛型是Java SE 1.5的新特性,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面和方法的建立中,分別稱為泛型類、泛型介面、泛型方法。 Java語言引入泛型的好處是安全簡單。

    泛型的好處是在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的,以提高程式碼的重用率。

---百度百科

JVM並不知道泛型的存在,因為泛型在編譯階段就已經被處理成普通的類和方法; 
處理機制是通過型別擦除,擦除規則:

  • 若泛型型別沒有指定具體型別,用Object作為原始型別;
  • 若有限定型別< T exnteds XClass >,使用XClass作為原始型別;
  • 若有多個限定< T exnteds XClass1 & XClass2 >,使用第一個邊界型別XClass1作為原始型別;

1.泛型擦除的體現


在寫程式碼時,無法把一個 String 型別的例項加到 ArrayList<Integer> 中,因為ArrayList<Integer> 和 ArrayList<String> 在編譯的時候是完全不同的型別,但是執行結果卻是true。這就Java泛型的型別擦除造成的


因為不管是 ArrayList<Integer> 還是 ArrayList<String>,在編譯完成後都會被編譯器擦除成了 ArrayList。

Java 泛型擦除是 Java 泛型中的一個重要特性,其目的是避免過多的建立類而造成的執行時的過度消耗。所以,想 ArrayList<Integer> 和 ArrayList<String> 這兩個例項,其類例項是同一個。

2.把Activity物件放進List<String>集合裡

當我們正常的將 Activity 物件放進 List<String> list = new ArrayList<>( ) 這樣的集合去,會報一個錯:


泛型的約束讓我們無法將 Activity 物件放進泛型為 String 的集合中去。那麼咋整呢?

通過泛型擦除的體現已經知道ArrayList<String>(或者ArrayList<Integer>)編譯後都是java.util.ArrayList,泛型的約束是在編譯時約束的,真正執行的 class 是沒有泛型約束的。所以只要在執行時將 Activity 物件加入List<String>中就可以了:

參考資料:

http://www.iteye.com/news/32333

http://blog.csdn.net/feipeng8848/article/details/66968382

https://mp.weixin.qq.com/s?__biz=MjM5OTE4ODgzMw==&mid=2247483703&idx=1&sn=9a10fc2edf9d4960845ab6da7807d01e&chksm=a73e01399049882f1c3487222cd5fe2262f66a00ab0ec0d0474710bbde3534932de67e91ea3e&scene=21#wechat_redirect