1. 程式人生 > >泛型中extends和super的區別

泛型中extends和super的區別

首先來說:< ? extends T > 叫 上界萬用字元
< ? super T >叫 下界萬用字元
1. 下面用程式碼來說明上界萬用字元的一些特點

public class Fruit {

}
public class Apple extends Fruit {

}
public class Banana extends Fruit{

}

public class Plate<T> {

    private T item;

    public Plate(T item) {
        super
(); this.item = item; } public T getItem() { return item; } public void setItem(T item) { this.item = item; } } //下面為測試程式碼 Plate<? extends Fruit> plate = new Plate<Apple>(new Apple()); Object item3 = plate.getItem(); Fruit item = plate.getItem(); Apple item2 = plate.getItem();//error
plate.setItem(new Apple());//error plate.setItem(new Banana());//error

1). plate< ? extends Fruit > 編譯器只知道容器內是存放的Fruit或者它的子類,但是並不知道是apple還是banana,只能知道上限是Fruit。
所以Apple item2 = plate.getItem();//error
2).原因是編譯器只知道容器內是Fruit或者它的派生類,但具體是什麼型別不知道。可能是Fruit?可能是Apple?也可能是Banana,編譯器在看到後面用Plate賦值以後,盤子裡沒有被標上有“蘋果”

。而是標上一個佔位符:CAP#1,來表示捕獲一個Fruit或Fruit的子類,具體是什麼類不知道,代號CAP#1。然後無論是想往裡插入Apple或者Banana或者Fruit編譯器都不知道能不能和這個CAP#1匹配,所以就都不允許。
所以:plate.setItem(new Apple());//error
plate.setItem(new Banana());//error

2 說明下界萬用字元的特點

Plate<? super Fruit> plate2 = new Plate<Fruit>(new Fruit());
        //取資料
        Object object = plate2.getItem();
        Fruit fruit = plate2.getItem();//error
        //存資料
        plate2.setItem(new Apple());
        plate2.setItem(new Banana());
        plate2.setItem(new Fruit());

因為下界規定了元素的最小粒度的下限,實際上是放鬆了容器元素的型別控制.元素的下界為Fruit,那麼存資料的時候,可以存Fruit的子類。但是注意:取資料時只有Object才能裝下,這樣做會使資料型別的資訊丟失。

3.PECS(product extends customer super)

            經常取資料時 用<? extends T>上界萬用字元
            經常存資料時 用<? super T>下界萬用字元