Java之泛型

泛型

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}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 泛型泛型就是指参数化类型,用符号标记是实际类型的占位符,是从JDK1.5出现的新特性。泛型可分为:泛型类泛型方法泛...
    罗伯特胡萝卜皮阅读 4,260评论 0 9
  • java之泛型(2) 接上一篇使用通配符(?) 通配符在上一篇中没有详细讲通配符的使用,萝卜刚开始学这儿的时候觉得...
    罗伯特胡萝卜皮阅读 3,352评论 0 0
  • 以下都是个人理解,若有错误,请多多批评 1. 例子 先定义如下继承关系 早期版本的Java代码(1): 之后引入了...
    我不吃甜食阅读 4,166评论 0 1
  • http://www.angelikalanger.com/GenericsFAQ/FAQSections/Par...
    wendy啦啦啦阅读 1,684评论 0 1
  • 2019年6月13日,星期四,雨 【作息】22:20,04:55 【学习】YY频道:13370530及总部YY群分...
    童珠兰阅读 1,621评论 0 1

友情链接更多精彩内容