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类