Thinking In Java Part10(泛型擦除)

1、泛型擦除  
    ArrayList<String> ArrayList<Integer> 我們可能認爲類型不同,但其實它們是相同的
        ArrayList<Integer> arrays= new ArrayList<>();
        ArrayList<String> arrays1= new ArrayList<>();
        arrays.add(2);
        arrays1.add("s");
        // true
        System.out.println(arrays.getClass().equals(arrays1.getClass()));
        // true
        System.out.println(arrays.getClass() == (arrays1.getClass()));
    Class.getTypeParameters()將返回一個TypeVariable對象數據,表示有泛型聲明所聲明的類型參數。但是我們從輸出中只能發現用作參數佔位符的標識符。
        因此:在泛型代碼內部,無法獲得任何有關泛型參數類型的信息。
    public static void main(String[] args) {
        ArrayList<Integer> arrays= new ArrayList<>();
        HashMap<Integer, Double> maps= new HashMap<>();
        // E
        System.out.println(Arrays.toString(arrays.getClass().getTypeParameters()));
        // K V
        System.out.println(Arrays.toString(maps.getClass().getTypeParameters()));
    }
    我們可以知道諸如類型參數標識符和泛型類型邊界這類信息——但是我們無法知道用來創建某個特定實例的實際的類型參數。
    Java泛型是使用擦除來實現的,意味着我們使用泛型時,任何具體的類型信息都被擦除,我們只知道我們在使用一個對象。

    泛型類型只有在靜態類型檢查期間纔出現,在此之後,程序中的所有泛型類型都將被擦除,替換爲它們的非泛型上界,比如List<T>將被擦除爲List,普通類型變量沒有指定邊界會被擦除爲OBject

    使用擦除的正當理由:從非泛化代碼到泛化代碼的轉變過程,以及在不破壞現有類庫的情況下,將泛型融入Java語言。 擦除使得先有的非泛型客戶端代碼能夠在不改變的情況下繼續使用,直至客戶端準備好用泛型重寫這些代碼。因爲它不會突然間破壞所有現有代碼。

    擦除的代價是顯著的,泛型不能用於顯示地引用運行時類型的操作之中,例如轉型、instanceof和new表達式。因爲所有關於參數的信息都丟失了。我們在使用泛型時必須時刻提醒自己 我們只是看起來好像擁有有關參數的類型 信息而已。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章