? 通配符類型安全
<? extends T> 表示類型的上界,表示參數化類型的多是T 或是 T的子類app
<? super T> 表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型的超類型(父類型),直至Objectui
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> 賦值。spa
Fruit fruit = flist.get(0); Apple apple = (Apple)flist.get(0);
因爲,其中放置是從Fruit中繼承的類型,因此能夠安全地取出Fruit類型。code
flist.contains(new Fruit()); flist.contains(new Apple());
在使用Collection中的contains 方法時,接受Object 參數類型,能夠不涉及任何通配符,編譯器也容許這麼調用。orm
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子類型限定的通配符能夠向泛型對象讀取。——《Core Java》