泛型
1.泛型的好处就是统一数据类型,操作更方便,将运行时异常提前至编译时,提高了效率,避免了强制类型的转换,可以将代码模板化,把数据类型当作参数传递,重用性更高了。
常见泛型编程案例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());
}
}
/**
* 泛型方法,该泛型变量使用方法上定义的泛型,一般由方法传入的参数决定
*/
public <E> void display(E e){
LogUtils.e(TAG,e.toString());
}
Book类包含id,name,price三个属性,produceBook就是创建该实例对象并且设置相应属性
Pen类包含id,name,price三个属性,producePen就是创建该实例对象并且设置相应属性
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));
}
运行结果
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}
泛型的上下限及通配符
使用的泛型类或接口时,如果传递的数据中的泛型类型不确定,可使用通配符<?>表示,但是使用通配符的话,就只能使用一些共性的方法,类似运行时多态,只有调用基类的方法一样。
如果不想使用通配符<?>表示所有类型的话,可以泛型的上下限。
<? 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三个类分为包、品牌名、特价包,produce相关方法如上,继承关系分别为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));
}
运行结果
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}
网友评论