溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

《Java架構(gòu)筑基》從Java基礎(chǔ)講起——泛型擦除

發(fā)布時間:2020-07-27 18:07:21 來源:網(wǎng)絡(luò) 閱讀:116 作者:未來可期_ 欄目:編程語言

一. 什么是泛型擦除

就是指編譯器編譯帶類型說明的集合時會去掉“類型”信息

二. 泛型擦除案例

泛型是提供給javac編譯器使用的,限定集合的輸入類型,編譯器編譯帶類型說明的集合時會去掉“類型”信息。

public class GenericTest {
    public static void main(String[] args) {
        new GenericTest().testType();
    }

    public void testType(){
        ArrayList<Integer> collection1 = new ArrayList<Integer>();
        ArrayList<String> collection2= new ArrayList<String>();

        System.out.println(collection1.getClass()==collection2.getClass());
        //兩者class類型一樣,即字節(jié)碼一致

        System.out.println(collection2.getClass().getName());
        //class均為java.util.ArrayList,并無實(shí)際類型參數(shù)信息
    }
}

輸出

true
java.util.ArrayList

為何會返回true

  • 這是因?yàn)椴还転榉盒偷念愋托螀魅肽囊环N類型實(shí)參,對于Java來說,它們依然被當(dāng)成同一類處理,在內(nèi)存中也只占用一塊內(nèi)存空間。從Java泛型這一概念提出的目的來看,其只是作用于代碼編譯階段,在編譯過程中,對于正確檢驗(yàn)泛型結(jié)果后,會將泛型的相關(guān)信息擦出,也就是說,成功編譯過后的class文件中是不包含任何泛型信息的。泛型信息不會進(jìn)入到運(yùn)行時階段。
  • 在靜態(tài)方法、靜態(tài)初始化塊或者靜態(tài)變量的聲明和初始化中不允許使用類型形參。由于系統(tǒng)中并不會真正生成泛型類,所以instanceof運(yùn)算符后不能使用泛型類。

使用反射可跳過編譯器,往某個泛型集合加入其它類型數(shù)據(jù)。

  • 只有引用類型才能作為泛型方法的實(shí)際參數(shù)
  • 例子:
public class GenericTest {
    public static void main(String[] args) {
        swap(new String[]{"111","222"},0,1);//編譯通過

        //swap(new int[]{1,2},0,1);
        //編譯不通過,因?yàn)閕nt不是引用類型

        swap(new Integer[]{1,2},0,1);//編譯通過
    }

    /*交換數(shù)組a 的第i個和第j個元素*/
    public static <T> void swap(T[]a,int i,int j){
        T temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

但注意基本類型有時可以作為實(shí)參,因?yàn)橛凶詣友b箱和拆箱。

  • 例子(編譯通過了):
public class GenericTest {
    public static void main(String[] args) {
        new GenericTest().testType();
        int a = biggerOne(3,5);
        //int 和 double,取交為Number
        Number b = biggerOne(3,5.5);
        //String和int 取交為Object
        Object c = biggerOne("1",2);
    }
    //從x,y中返回y
    public static <T> T biggerOne(T x,T y){
        return y;
    }
}
  • 同時,該例還表明,當(dāng)實(shí)參不一致時,T取交集,即第一個共同的父類。
  • 另外,如果用Number b = biggerOne(3,5.5);改為String c = biggerOne(3,5.5);則編譯報(bào)錯:
Error:(17, 29) java: 不兼容的類型: 推斷類型不符合上限
    推斷: java.lang.Number&java.lang.Comparable<? extends java.lang.Number&java.lang.Comparable<?>>
    上限: java.lang.String,java.lang.Object
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI