Java泛型:泛型擦除詳細介紹、泛型擦除的體現


泛型擦除

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


泛型擦除的體現

通過以下代碼來感受以下什么是泛型擦除:

public class Erase {

    public static void main(String[] args) {
    	// 創建兩個不同泛型的list集合
        List<Integer> integerList = new ArrayList<>();
        List<String> stringList = new ArrayList<>();
        
        System.out.println(integerList.getClass() == stringList.getClass());

        System.out.println("integerList----> "+integerList.getClass().getName());
        System.out.println("stringList----> "+stringList.getClass().getName());
    }
}

輸出結果

true
integerList----> java.util.ArrayList
stringList----> java.util.ArrayList

很明顯發現,兩個集合的泛型不同,但是比較class,返回的是true,並且通過反射獲取到的className是java.util.ArrayList
不管是 ArrayList<Integer> 還是 ArrayList<String>,在編譯完成后都會被編譯器擦除成了 ArrayList。

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


可以把其他類型的數據放到指定了泛型的list集合中嗎?

當然是可以的。因為泛型擦除的原因。完全可以將不相干的類型的數據存入指定泛型的集合中。

如下所示添加,肯定是要報錯的,因為在編譯的時候設定了規則,編譯是不可能通過的。
在這里插入圖片描述

按理說,因為泛型擦除的原因,完全是可以將不相干類型的數據放到指定泛型的集合中的。其實,可以換一種思路,當list集合運行起來之后,這個list集合因為泛型擦除是沒有指定泛型的,即class是沒有泛型的,所以可以在運行期間獲取這個list集合,然后將值放到該list集合中。

public class Erase {
    
    public static void main(String[] args) {
        Erase erase = new Erase();
        erase.testErase();
    }

    List<Integer> integerList = new ArrayList<>();
    List<String> stringList = new ArrayList<>();

    public void testErase(){
        Double d = 10d;
        try {
        	// 通過反射機制獲取字段,然后將double類型的數據放入泛型為Integer集合中
            Field integerField = this.getClass().getDeclaredField("integerList");
            integerField.setAccessible(true);
            List integerFieldList = (List) integerField.get(this);
            integerFieldList.add(d);

			// 通過反射機制獲取字段,然后將double類型的數據放入泛型為String集合中
            Field stringField = this.getClass().getDeclaredField("stringList");
            stringField.setAccessible(true);
            List stringFieldList = (List) stringField.get(this);
            stringFieldList.add(d);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("integerList ---> "+integerList);
        System.out.println("stringList ---> "+stringList);
    }
}

輸出結果

integerList ---> [10.0]
stringList ---> [10.0]


免責聲明!

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



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