java 泛型萬用字元 extends, super

來源:互聯網
上載者:User

標籤:

引自:http://sharewind.iteye.com/blog/1622164

關鍵字說明
  • ? 萬用字元類型
  • <? extends T> 表示類型的上界,表示參數化型別的可能是T 或是 T的子類
  • <? super T> 表示類型下界(Java Core中叫超類型限定),表示參數化型別是此類型的超類型(父類型),直至Object
extends 樣本
static class Food{}static class Fruit extends Food{}static class Apple extends Fruit{}static class RedApple extends Apple{}List<? extends Fruit> flist = new ArrayList<Apple>();// complie error:// flist.add(new Apple());// flist.add(new Fruit());// flist.add(new Object());flist.add(null); // only work for null 

List<? extends Frut> 表示 “具有任何從Fruit繼承類型的列表”,編譯器無法確定List所持有的類型,所以無法安全的向其中添加對象。可以添加null,因為null 可以表示任何類型。所以List 的add 方法不能添加任何有意義的元素,但是可以接受現有的子類型List<Apple> 賦值。

Fruit fruit = flist.get(0);Apple apple = (Apple)flist.get(0);

由於,其中放置是從Fruit中繼承的類型,所以可以安全地取出Fruit類型。

flist.contains(new Fruit());flist.contains(new Apple());

在使用Collection中的contains 方法時,接受Object 參數類型,可以不涉及任何萬用字元,編譯器也允許這麼調用。

super 樣本
List<? super Fruit> flist = new ArrayList<Fruit>();flist.add(new Fruit());flist.add(new Apple());flist.add(new RedApple());// compile error:List<? super Fruit> flist = new ArrayList<Apple>();

List<? super Fruit> 表示“具有任何Fruit超類型的列表”,列表的類型至少是一個 Fruit 類型,因此可以安全的向其中添加Fruit 及其子類型。由於List<? super Fruit>中的類型可能是任何Fruit 的超類型,無法賦值為Fruit的子類型Apple的List<Apple>.

// compile error:Fruit item = flist.get(0);

因為,List<? super Fruit>中的類型可能是任何Fruit 的超類型,所以編譯器無法確定get返回的物件類型是Fruit,還是Fruit的父類Food 或 Object.

小結
extends 可用於的傳回型別限定,不能用於參數類型限定。super 可用於參數類型限定,不能用於傳回型別限定。>帶有super超類型限定的萬用字元可以向泛型對易用寫入,帶有extends子類型限定的萬用字元可以向泛型對象讀取。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

我的理解:

泛化:給容器指定一種物件類型。在java中,子類可以賦值給父類容器,即向上賦值;而父類不可以賦值給子類容器,因為向下賦值需要增添新的屬性等資訊,這是無法完成的,即不能向下賦值。

===》List< ? super Fruit >

  • 表示List裡存放的都是 Fruit 和 Fruit 的父類,但是在編譯的時候並不清楚具體是哪個父類。
  • 直接向 List 賦值時,必須滿足容器物件要求,從而必須賦值為 Fruit 或 Fruit 的父類。 因為編譯時間,完全符合要求,所以可以通過編譯。在運行時,必須要確定 List 裡放的是什麼類型的對象。如果放 Fruit 子類,那麼根本不知道要把 Fruit 子類泛化為哪種類型,從而最終運行時 List 存放的物件類型是不確定的。
  • 可以向 List add 任何 Fruit 和 Fruit 的子類。因為在編譯時間,可以確定 List 中至少是 Fruit,因此 Fruit 和 Fruit 子類 至少可以向上賦值給 Fruit,當然也可能賦值給 Fruit 父類,所以編譯通過。 而在運行時,List 中存放的具體是 Fruit 的哪個父類已經確定了,add 的元素會直接轉換為該父類,所以運行通過。
  • super 用於add元素,不用於 get 元素。因為編譯時間不確定是哪個父類,由於泛化限定,get只能賦值給 當前類型及其父類,那麼只能賦值給 Object 對象了。所以 Object o = flist.get(0) 是可以的。

===》List< ? extends Fruit >

  • 表示 List 裡存放的都是 Fruit 和 Fruit 的子類,但是在編譯的時候並不清楚具體是哪個子類。
  • 直接向 List 賦值時,必須滿足容器物件要求,從而必須賦值為 Fruit 或 Fruit 的子類。這雷根本不可能賦值為父類,因為這違反了泛化的基本要求。
  • get元素可以賦值給 Fruit 和 Fruit 父類。因為 List 中存放的至多是 Fruit 類,所以向上賦值時, Fruit 和 Fruit 父類都是滿足要求的。
  • extends 用於get元素,不用於add元素。不可以向 List add 元素。因為編譯時間不確定 List 中存放的是哪個 Fruit 子類,如果 add 了某個子類,eg. Orange,而實際儲存的是 Apple,那麼根本類型就不匹配。所以只能add null。

 

 

 

 

 

 

 

 

 

 

 

 

 

java 泛型萬用字元 extends, super

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.