基礎知識-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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM