Java泛型探索

1.關於泛型擦除

public class ErasedType {
    public static void main(String[] args) {
        Class c1 = new ArrayList<Integer>().getClass();
        Class c2 = new ArrayList<String>().getClass();
        System.out.println(c1 == c2);
    }
}

上面代碼的輸出結果爲:

class Frop {
}

class Fnorkle {
}

class Quark<Q> {
}

class Particle<POOSITION, MOMENTUM> {
}


public class ErasedType {
    public static void main(String[] args) {
        List<Frop> list = new ArrayList<Frop>();
        Map<Frop, Fnorkle> map = new HashMap<Frop, Fnorkle>();
        Quark<Fnorkle> quark = new Quark<Fnorkle>();
        Particle<Long, Double> particle = new Particle<Long, Double>();
        System.out.println(Arrays.toString(list.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(map.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(quark.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(particle.getClass().getTypeParameters()));
    }
}

 以上代碼的輸出結果爲:

從以上內容可以發現,在泛型代碼的內部,無法獲得任何有關泛型參數類型的信息。

由第一個例子可以看出在運行時他們是相同的類型。

第二個例子只是看到了佔位符的標識符,沒有任何有用的信息。

2.擦除的問題

泛型不能用於顯式的引用運行時類型的操作之中,例如轉型、instanceof以及new。

class Frop<T> {
}

class Cat {
}


public class ErasedType {
    public static void main(String[] args) {
        Frop<Cat> frop = new Frop<Cat>();
    }
}

 上述代碼中,只是看起來擁有相關參數的類型信息,T被Cat所替換,但是實際上並非如此,它只是一個Object。

3.擦除的補償

class Building {
}

class House extends Building {
}


public class ErasedType<T> {
    Class<T> kind;

    public ErasedType(Class<T> kind) {
        this.kind = kind;
    }

    public boolean f(Object obj){
        return kind.isInstance(obj);
    }

    public static void main(String[] args) {
        ErasedType<Building> ctt1=new ErasedType<Building>(Building.class);
        System.out.println(ctt1.f(new Building()));
        System.out.println(ctt1.f(new House()));
        ErasedType<House> ctt2=new ErasedType<House>(House.class);
        System.out.println(ctt2.f(new Building()));
        System.out.println(ctt2.f(new House()));
    }
}

有時可以通過引入類型標籤對擦除進行補償,這意味着,有時候需要顯式地將類型的Class對象進行傳遞。以便可以在類型表達式中使用。

4.邊界

因爲擦除移除了類型信息,但是泛型重用了extends關鍵字爲泛型參數類型上設置限制條件。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章