基礎知識-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.class檔案載入進jvm之後,只會存在一份地址相同的ArrayList的Class類,所以雖然編譯時是List<String> 和 List<Integer>,但是執行時泛型擦除了,他們的class類(也就是getClass()方法獲得的)都是同一個,在編譯完成後都會被編譯器擦除成了 ArrayList(地址也相同)。只不過該Class類有兩個例項物件l1和l2而已,兩個例項物件的地址不同。
Java 泛型擦除是 Java 泛型中的一個重要特性,其目的是避免過多的建立類(這裡指類載入器載入的Class類物件,只有一份)而造成的執行時的過度消耗。所以,像ArrayList<Integer> 和 ArrayList<String> 這兩個例項,其類例項(Class類)是同一個。也就是同一個Class類例項產生了ArrayList<Integer> 和 ArrayList<String> 兩個例項物件,Class類例項地址是同一個,兩個例項物件的地址不同,即上圖會出現:l1.getClass() == l2.getClass() 返回true,但是l1 == l2 返回false.
2.把Activity物件放進List<String>集合裡
當我們正常的將 Activity 物件放進 List<String> list = new ArrayList<>( ) 這樣的集合去,編譯就會報一個錯:
泛型的約束讓我們無法將 Activity 物件放進泛型為 String 的集合中去。那麼咋整呢?
通過泛型擦除的體現已經知道ArrayList<String>(或者ArrayList<Integer>)編譯後都是java.util.ArrayList,泛型的約束是在編譯時約束的,真正執行的 class 是沒有泛型約束的。所以只要在執行時將 Activity 物件加入List<String>中就可以了:
轉載:https://blog.csdn.net/qq_30878303/article/details/79639904
TRANSLATE with x English TRANSLATE with EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back 帶著疑問去思考,然後串聯,進而歸納總結,不斷追問自己,進行自我辯證,像偵查嫌疑案件一樣看待技術問題,漆黑的街道,你我一起尋找線索,你就是技術界大偵探福爾摩斯