public class Test { public static void main(String [] args){ Plate<? extends Fruit> p = new Plate<Apple>(new Apple()); Food food = p.get(); Fruit fruit = p.get(); //ERROR // p.set(new Fruit()); // p.set(new Orange()); // p.set(new Apple()); //error // Apple apple = p.get(); Plate<? super Fruit> p1 = new Plate<Fruit>(new Fruit()); p1.set(new Apple()); p1.set(new Orange()); p1.set(new Fruit()); Object object = p1.get(); } } class Plate<T>{ private T item; public Plate(T t){ item = t; } public T get() { return item; } public void set(T item) { this.item = item; } } //父類 class Food { void eatFood(){ System.out.println("eatFood"); } } //子類1 class Fruit extends Food{ void eatFruit(){ System.out.println("eatFruit"); } } class Meat extends Food{ void eatMeat(){ System.out.println("eatMeat"); } } //子類2 class Apple extends Fruit{ void eatApple(){ System.out.println("eatApple"); } } class Orange extends Fruit{ void eatOrange(){ System.out.println("eatOrange"); } } class Pork extends Meat{ void eatPork(){ System.out.println("eatPork"); } } class Beaf extends Meat{ void eatBeaf(){ System.out.println("eatBeaf"); } }
<? extends Fruit> 相當於是什么意思? 就是 ? extends Fruit 里面是Fruit類或者他的子類但是具體什么類型不知道
所以可能是Fruit 可能是Apple可能是Orange 這里面相當於標記了一個占位符:CAP#1 但是不能插入他的子類了,
<?> 不寫默認是<? extends Object>
所以取得時候只能取父類的類型 向下轉型嘛 父類new子類對象可以
所以這種寫法適合去取 因為set會失效
Plate相當於一個容器 <?>與<T>不同的是 <T>是可以已知的
<? extends Fruit> 規定了他的上界限是 Fruit 但是下面的類型不能確定
所以我不能存,因為如果我的下面的類型細度比較大,存進去的時候就會有信息丟失 ,但是我取的時候可以取他父類的類型這樣就沒有丟失
相反的可以這樣 <? super Fruit> 這里面存的是Fruit的父類 那么就不能插入Fruit的父類了 但是向下轉型只要是子類都是可以
放進去,粒度比這個小都可以放進去
取得時候只能取到<? super Fruit> 相當與是沒有上限的父類 那就是Object類
