Java泛型中<? extends E>和<? super E>的區別__Java

來源:互聯網
上載者:User

         這篇文章談一談Java泛型聲明<。 extends E>和<。 super E>的作用和區別 <。 extends E>

           <? extends E> 是 Upper Bound(上限) 的萬用字元,用來限制元素的類型的上限,比如

List<? extends Fruit> fruits;
表示集合中的元素類型上限為Fruit類型,即只能是Fruit或者Fruit的子類,因此對於下面的賦值是合理的

fruits = new ArrayList<Fruit>();fruits = new ArrayList<Apple>();
如果集合中元素類型為Fruit的父類則會編譯出錯,比如

fruits = new ArrayList<Object>();//編譯不通過
           有了上面的基礎,接著來看看 <? extends E>限定的集合的讀寫操作

1、寫入

           因為集合fruits中裝的元素類型為Fruit或Fruit子類,直覺告訴我們,往fruits中添加一個Fruit類型對象或其子類對象是可行的

fruits.add(new Fruit());//編譯不通過fruits.add(new Apple());//編譯不通過
           結果是編譯都不通過,為什麼。因為<? extends Fruit>只是告訴編譯器集合中元素的類型上限,但它具體是什麼類型編譯器是不知道的,fruits可以指向ArrayList<Fruit>,也可以指向ArrayList<Apple>、ArrayList<Banana>,也就是說它的類型是不確定的,既然是不確定的,為了型別安全,編譯器只能阻止添加元素了。舉個例子,當你添加一個Apple時,但fruits此時指向ArrayList<Banana>,顯然類型就不相容了。當然null除外,因為它可以表示任何類型。

2、讀取 

           無論fruits指向什麼,編譯器都可以確定擷取的元素是Fruit類型,所有讀取集合中的元素是允許的

Fruit fruit = fruits.get(0);//編譯通過

補充:<?>是<? extends Object>的簡寫 <。 super E>

      <? super E> 是 Lower Bound(下限) 的萬用字元 ,用來限制元素的類型下限,比如

List<? super Apple> apples;
表示集合中元素類型下限為Apple類型,即只能是Apple或Apple的父類,因此對於下面的賦值是合理的

apples = new ArrayList<Apple>();apples = new ArrayList<Fruit>();apples = new ArrayList<Object>();
如果元素類型為Apple的子類,則編譯不同過
apples = new ArrayList<RedApple>();//編譯不通過

同樣看看<? super E>限定的集合的讀寫操作


1、寫入

        因為apples中裝的元素是Apple或Apple的某個父類,我們無法確定是哪個具體類型,但是可以確定的是Apple和Apple的子類是和這個“不確定的類”相容的,因為它肯定是這個“不確定類型”的子類,也就是說我們可以往集合中添加Apple或者Apple子類的對象,所以對於下面的添加是允許的

apples.add(new Apple());apples.add(new RedApple());
它無法添加Fruit的任何父類對象,舉個例子,當你往apples中添加一個Fruit類型對象時,但此時apples指向ArrayList<Apple>,顯然類型就不相容了,Fruit不是Apple的子類

apples.add(new Fruit());//編譯不通過
2、讀取

        編譯器允許從apples中擷取元素的,但是無法確定的擷取的元素具體是什麼類型,只能確定一定是Object類型的子類,因此我們想獲得儲存進去的對應類型的元素就只能進行強制類型轉換了

Apple apple = (Apple)apples.get(0);//擷取的元素為Object類型
問題來了,JDK1.5引入泛型的目的是為了避免強制類型轉換的繁瑣操作,那麼使用泛型<? super E>幹嘛呢。這裡就得談到泛型PECS法則了

PECS法則 PECS法則:生產者(Producer)使用extends,消費者(Consumer)使用super
1、生產者        如果你需要一個提供E類型元素的集合,使用泛型萬用字元<? extends E>。它好比一個生產者,可以提供資料。 2、消費者        如果你需要一個只能裝入E類型元素的集合,使用泛型萬用字元<? super E>。它好比一個消費者,可以消費你提供的資料。 3、既是生產者也是消費者        既要儲存又要讀取,那就別使用泛型萬用字元。 PECS例子 JDK集合操作協助類Collections中的例子

    /**     * Copies all of the elements from one list into another.  After the     * operation, the index of each copied element in the destination list     * will be identical to its index in the source list.  The destination     * list must be at least as long as the source list.  If it is longer, the     * remaining elements in the destination list are unaffected. <p>     *     * This method runs in linear time.     *     * @param  dest The destination list.     * @param  src The source list.     * @throws IndexOutOfBoundsException if the destination list is too small     *         to contain the entire source List.     * @throws UnsupportedOperationException if the destination list's     *         list-iterator does not support the <tt>set</tt> operation.     */    public static <T> void copy(List<? super T> dest, List<? extends T> src) {        int srcSize = src.size();        if (srcSize > dest.size())            throw new IndexOutOfBoundsException("Source does not fit in dest");        if (srcSize < COPY_THRESHOLD ||            (src instanceof RandomAccess && dest instanceof RandomAccess)) {            for (int i=0; i<srcSize; i++)                dest.set(i, src.get(i));        } else {            ListIterator<? super T> di=dest.listIterator();    ListIterator<? extends T> si=src.listIterator();            for (int i=0; i<srcSize; i++) {                di.next();                di.set(si.next());            }        }    }
總結         為什麼要引入泛型萬用字元。一句話:為了保證型別安全。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.