Java泛型_上界extends_下界superjava
? 通配符類型安全
<? extends T> 表示類型的上界,表示參數化類型的多是T或是T的子類spa
<? super T> 表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型(T)的超類型(父類型),直至Objectcode
以下代碼,繼承
/** * 代碼中通配符<?> 是 <? extends Object> 的簡寫 * * @param list */ public static void test(List<?> list) { Object e = list.get(0); // get OK // list.set(0, e); // set 編譯報錯 list.set(0, new Integer(1)); //編譯報錯 }
set報錯的緣由是由於此時方法中的類型是不可具體化的,你能夠傳遞一個String,Number,Book,等任何繼承自Object的類做爲List的參數類型給test方法,get
而list要求集合中的類型必須是一致的,set的時候沒有辦法保證set進去的數據類型是否和list中本來的類型一致,好比你傳給test方法的是 List<Book>, 那麼在方法中set進去一個Object顯然類型就不一致了。這也是通配符帶來靈活性的同時所要付出的代價。編譯
結論:使用了 <? extends T> 這樣的通配符,test方法的參數list變成了只能get不能set(除了null) 或者不嚴謹的說它變成了只讀參數了, 有些相似一個生產者,只提供數據。class
/** * list 是一個列表 * 列表元素所有必須是Number的超類型(父類型),直至Object(不包含Object) * * @param list */ public static void test(List<? super Number> list) { Number n = list.get(0); // 編譯錯誤 Object o = list.get(0); // OK list.set(0, new Object()); // 編譯錯誤 Number number = new Integer(0); list.set(0, number); // OK list.set(0, new Long(0)); // OK list.set(0, new Integer(0)); // OK }
List<? super Number> 表示「列表中包含的元素的類型是Number的超類型」,列表的類型至少是一個Number類型,所以能夠安全的向其中添加Number及其子類型。List<? super Number>中的類型多是任何Number的超類型。test
============END============泛型