void set(? extends someclass);
? extends someclass get();
我們使用萬用字元通常是希望某乙個例項可以向上轉型 例:
listlist = new arraylist() //compile error
list<? extends animal> list = new arraylist() //compile ok
這些是基本的概念,在這兒我就不再概述為什麼了,我們要講的是為什麼上界限定(? extends someclass)使用set方法
編譯錯誤,而使用get方法卻是安全的呢?
讓我們先考慮一下陣列,假如你以如下的形式建立了乙個陣列.
animal ani = new dog(10); //compile ok
利用了向上轉型的多型思想,這是完全合法的 現在我們設想向裡面新增元素。
ani[0] = new dog() //compile ok ,runtime ok
ani[1] = new animal() //compile ok , runtime error
我們知道現在操縱的是dog型別的陣列,但是編譯器不知道(只有在執行時,ani引用才和dog陣列建立聯絡),編譯的時候編譯器沒
有理由會拒絕存放animal型別的物件,因為他本身就是乙個animal型別的引用。
陣列擁有特殊的保護機制,即使在編譯時期插入了錯誤的物件,執行時也能發現並丟擲這些異常,所以也沒必要為此擔心什麼。
現在假設你運用的是泛型,你能不能這樣做呢? 現在考慮如下例子
list<? extends animal> list = new arraylist() //compile ok
這也是向上轉型。
但有一點和陣列不同的是,陣列在編譯階段就確定了他是什麼型別的陣列引用(如上例是animal型別的陣列引用),而帶泛型的list呢?他只知道他是乙個某型別的list引用,只知道這個「某型別」是繼承自animal的類,具體是dog,cat,還是monkey呢,他一無所知。
你可能會提出疑問,後面不是跟了 new arraylist() 嗎,這不是在告訴他他是乙個dog型別的arraylist引用嗎?很遺憾,編譯器沒有那麼聰明,這些只會在執行時建立聯絡,然而執行時的型別擦除又讓他們攜帶的資訊煙消雲散,你也就無法期待這些東西在執行時會給你什麼驚喜了。
那如果想向我們剛建好list裡面新增元素呢 如add(new dog()) 或者add(new animal()) (和set一樣,在此以add為例更好)
list.add(new dog()) //compile error
list.add(new animal()) //compile error
編譯器拒絕一切為其新增元素的操作(傳參操作),為什麼?因為 list<? extends animal> list 無法確定他具體是什麼類,就像list只能為其新增animal及animal的子類元素一樣,你乙個連具體是什麼類都不知道的引用,編譯器自然認為任何新增都是不安全的。
讓我們再舉個容易理解的例子,我們暫時僅僅只觀察這個式子-------list
<? extends animal> 現在我們假設?是cat,那麼我們能做些什麼?
我們能向裡面新增 cat和cat的子類元素,但是我們不能新增dog,monkey甚至是animal元素。
那現在返回來,編譯器無法得知 ? 具體是什麼型別,那 ?可能是cat,也可能是dog 或者其他的繼承自animal的類,我們又怎麼能確定哪些add是安全的,哪些add是非法的呢?
所以我們自然無法使用add或者set方法。
我們知道get方法返回乙個值,這個值只要是確定的編譯器就可以接受,現在考慮如下例子
listtest = new arraylist();
test.add(new cat());
list<? extends animal> list = test;
animal ani = list.get(0); //compile ok,runtime ok
get方法為什麼合理? 因為他有乙個確定的返回值。 ? extends animal 的返回值一定是乙個animal型別的 如果你對這句話有異議,那我建議你再回去溫習一下有關多型的知識,這確實是多型的乙個體現,不管你?是代表cat dog 還是monkey 這些類的共通點就是他們都是繼承自animal的,這點編譯器心知肚明,自然也就不會有任何異議和不確定性,所以get方法確實是合理的
泛型的萬用字元
萬用字元 wildcard 例如 public class testwildcards 舉例 想要宣告乙個方法,可以把乙個collection集合src中的所有元素,新增到另乙個collection集合dest中 public void copy collection src,collection ...
泛型的萬用字元
當使用泛型類或者泛型介面,傳遞的資料中,泛型的型別不確定,可以通過通 配符表示。一旦程式使用了泛型的萬用字元後,只能使用object類中的共性的 方法,集合中自身元素的方法無法使用。萬用字元的基本使用 泛型的萬用字元 不知道使用什麼型別來接受的時候,此時可以使用 代表未知 的萬用字元。此時只能接受資...
泛型萬用字元 與 有限制的泛型萬用字元
一 泛型萬用字元 子父類關係 list list1 newarraylist list list2 newarraylist list1 list2 編譯錯誤 list list null list list1 list list2 結論 讀寫問題 collection c newarraylist...