廢話不多說(shuō),先上代碼,大家可以貼在單元測(cè)試中看下以方便理解
public class ExampleUnitTest {
class Food{}
class Fruit extends Food{}
class Meat extends Food{}
class Apple extends Fruit{}
class Banana extends Fruit{}
class Pork extends Meat{}
class Beef extends Meat{}
class RedApple extends Apple{}
class GreenApple extends Apple{}
class Plate<T> {
private T item;
public Plate(T t){
this.item = t;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
}
@Test
public void test(){
//下面這句編譯報(bào)錯(cuò)可以這樣理解Apple is a Fruit,but Apple's Plate is not Fruit's Plate
// Plate<Fruit> plate = new Plate<Apple>(new Apple()); //Error,編譯報(bào)錯(cuò)
//上界通配符,Plate能裝所有的Fruit及Fruit的子類(lèi)
Plate<? extends Fruit> plate1 = new Plate<>(new Apple());
// plate1.setItem(new Apple()); //Error 編譯器不通過(guò) 無(wú)法賦值
// plate1.setItem(new Fruit()); //Error 無(wú)法賦值
//為什么即使已經(jīng)指定了Apple類(lèi)型卻還是會(huì)報(bào)錯(cuò),是因?yàn)榫幾g器只知道容器內(nèi)是Fruit或者它的子類(lèi)
//上界只能從盤(pán)中取出,取出來(lái)的東西只能放在Fruit以及Fruit的基類(lèi)中
Fruit item1 = plate1.getItem();//正確或有效用法
Object object = plate1.getItem();
// Apple item = plate1.getItem(); //Error 類(lèi)型不匹配
//下界通配符規(guī)定了元素最小粒度的下限,既然元素是Fruit以及Fruit類(lèi)型的基類(lèi),
// 那么往里存的粒度只要比Fruit類(lèi)型小的都可以
Plate<? super Fruit> plate3 = new Plate<>(new Fruit());
Plate<? super Fruit> plate4 = new Plate<>(new Food());
Object item = plate3.getItem();//如果接收只能用Object類(lèi)型,但取這個(gè)值毫無(wú)意義
//實(shí)際定義super下界通配符是為了set()賦值,但必須保證是Fruit以及Fruit的子類(lèi)型才能編譯通過(guò)
plate3.setItem(new Fruit());
plate3.setItem(new Apple());
plate3.setItem(new RedApple());
// plate3.setItem(new Food());//Error
// plate4.setItem(new Food());//Error
plate4.setItem(new Apple());
plate4.setItem(new GreenApple());
}
}
總之一句話,頻繁往外讀取內(nèi)容用上界Extends,經(jīng)常往里寫(xiě)入的適合用下界Super