Java泛型_上界extends_下界super

Java泛型_上界extends_下界superjava

? 通配符類型安全

<? extends T> 表示類型的上界,表示參數化類型的多是T或是T的子類spa

<? super T> 表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型(T)的超類型(父類型),直至Objectcode


當使用 Upper Bound 的通配符時

以下代碼,繼承

/**
 * 代碼中通配符<?> 是 <? 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


當使用 Lower Bound 的通配符時

/**
 * 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============泛型

相關文章
相關標籤/搜索