泛型
1.泛型的好處就是統(tǒng)一數(shù)據(jù)類型,操作更方便,將運(yùn)行時(shí)異常提前至編譯時(shí),提高了效率,避免了強(qiáng)制類型的轉(zhuǎn)換,可以將代碼模板化,把數(shù)據(jù)類型當(dāng)作參數(shù)傳遞,重用性更高了。
常見泛型編程案例RxJava源碼的操作符,包括泛型的上下限操作。
定義
public class Shop<T> {
/**
* 定義泛型的類或接口,常見的泛型變量用T、R、K、V和E
* 修飾符class類名或interface接口名 <泛型變量>{
*
* }
*/
private static final String TAG = Shop.class.getSimpleName();
private ArrayList<T> list = new ArrayList<>();
/**
* 方法上包含泛型變量,該泛型變量使用類上定義的泛型
*/
public void addGood(T t){
if (t != null){
list.add(t);
}
}
public void displayGoods(){
for (T t : list) {
LogUtils.e(TAG, "display ==> " + t.toString());
}
}
/**
* 泛型方法,該泛型變量使用方法上定義的泛型,一般由方法傳入的參數(shù)決定
*/
public <E> void display(E e){
LogUtils.e(TAG,e.toString());
}
Book類包含id,name,price三個(gè)屬性,produceBook就是創(chuàng)建該實(shí)例對(duì)象并且設(shè)置相應(yīng)屬性
Pen類包含id,name,price三個(gè)屬性,producePen就是創(chuàng)建該實(shí)例對(duì)象并且設(shè)置相應(yīng)屬性
public static void main(String[] args){
Shop<Book> shop = new Shop<>();
shop.addGood(produceBook("1","Maths",20f));
shop.addGood(produceBook("2","English",25f));
shop.addGood(produceBook("3","Java",30f));
shop.displayGoods();
shop.display(producePen("1","Black Pen",2f));
}
運(yùn)行結(jié)果
display ==> Book{id=1,name=Maths,price=20.0}
display ==> Book{id=2,name=English,price=25.0}
display ==> Book{id=3,name=Java,price=30.0}
Pen{id='1', name='Black Pen', price=2.0}
泛型的上下限及通配符
使用的泛型類或接口時(shí),如果傳遞的數(shù)據(jù)中的泛型類型不確定,可使用通配符<?>表示,但是使用通配符的話,就只能使用一些共性的方法,類似運(yùn)行時(shí)多態(tài),只有調(diào)用基類的方法一樣。
如果不想使用通配符<?>表示所有類型的話,可以泛型的上下限。
<? extends 類名> 代表只能使用該類和該類的子類,稱之為泛型的下限。
<? super 類名> 代表只能使用該類和該類的父類,稱之為泛型的上限。
public class Market<T> {
public void show(Shop<? extends T> shop){
shop.displayGoods();
}
public void display(Shop<? super T> shop){
shop.displayGoods();
}
}
Bag、BrandBag、BargainPriceBag三個(gè)類分為包、品牌名、特價(jià)包,produce相關(guān)方法如上,繼承關(guān)系分別為BargainPriceBag繼承BrandBag,BrandBag繼承Bag
public static void main(String[] args){
Shop<Bag> bagShop = new Shop<>();
bagShop.addGood(produceBag("1","Red Bag",25f));
bagShop.addGood(produceBag("2","Blue Bag",25f));
Shop<BrandBag> brandBagShop = new Shop<>();
brandBagShop.addGood(produceBrandBag("1","Black Bag",500f,"LV"));
brandBagShop.addGood(produceBrandBag("2","Black Bag",500f,"Gucci"));
Shop<BargainPriceBag> bargainPriceBagShop = new Shop<>();
bargainPriceBagShop.addGood(produceBargainPriceBag("1","Black Bag",500f,"LV",250f));
bargainPriceBagShop.addGood(produceBargainPriceBag("2","Red Bag",500f,"LV",200f));
}
運(yùn)行結(jié)果
use ? super T
display ==> Bag{id=1,name=Red Bag,price=25.0}
display ==> Bag{id=2,name=Blue Bag,price=25.0}
display ==> BrandBag{id=1,name=Black Bag,price=500.0,brand=LV}
display ==> BrandBag{id=2,name=Black Bag,price=500.0,brand=Gucci}
use ? extends T
display ==> BrandBag{id=1,name=Black Bag,price=500.0,brand=LV}
display ==> BrandBag{id=2,name=Black Bag,price=500.0,brand=Gucci}
display ==> BrandBag{id=1,name=Black Bag,price=500.0,brand=LV,bargainPrice=250.0}
display ==> BrandBag{id=2,name=Red Bag,price=500.0,brand=LV,bargainPrice=200.0}