Java泛型的基本使用
2015-10-10 13:29
513 查看
Java1.5版本推出了泛型,虽然这层语法糖给开发人员带来了代码复用性方面的提升,但是这不过是编译器所做的一层语法糖,在真正生成的字节码中,这类信息却被擦除了。笔者发现很多几年开发经验的程序员,依然不善于使用Java泛型,本文将从Java泛型的基本使用入手,在今后的多篇博文里,对泛型的使用做个总结。本文不会深入Java泛型的实现原理,只会介绍Java泛型的使用。
代码清单1
代码清单2
现在我们可以使用Decorator给List添加或者打印任何类型了,如代码清单3所示。
代码清单3
listB的泛型Table的确是decoratorA的泛型Auction的子类型,但是编译器会报错,说明不允许这种语法。
如何解决这个问题?请看下一篇《Java泛型的协变》
实验准备
首先需要创建一个类继承体系。以商品为例,每种商品都有基本的名称属性。在大数据应用中,数据表和服务都可以作为商品,表有行数属性,服务有方法属性,实现如代码清单1所示。代码清单1
class Auction { private String name; public Auction(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return name; } } class Table extends Auction { private Integer rowNum; public Table(String name, Integer rowNum) { super(name); this.rowNum = rowNum; } public Integer getRowNum() { return rowNum; } public void setRowNum(Integer rowNum) { this.rowNum = rowNum; } public String toString() { return super.toString() + ", rowNum :" + rowNum; } } class Service extends Auction { private String method; public Service(String name, String method) { super(name); this.method = method; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String toString() { return super.toString() + ", method :" + method; } }
实验:泛型最基本使用
现在为了演示泛型的使用,还是以商品为例。数据表本身只是Hbase中的一张表,而服务是运行于Hadoop Yarn之上的一个数据服务,比如说是Strom、Spark或者Oozie。无论是数据表还是服务,它本身并不是商品,要成为商品,必须有个装饰器将它包装为商品,现在我们用泛型实现一个简单的装饰器,见代码清单2所示。代码清单2
class Decorator<T> { /** * * 描 述:Exp1使用<br/> * 作 者:jiaan.gja<br/> * 历 史: (版本) 作者 时间 注释 <br/> * @param itemList */ public void doDecorate(List<T> itemList) { for(int i = 0; i < itemList.size(); i++) { System.out.println(itemList.get(i)); } } /** * * 描 述:Exp1使用<br/> * 作 者:jiaan.gja<br/> * 历 史: (版本) 作者 时间 注释 <br/> * @param itemList * @param t */ public void addDecorate(List<T> itemList, T t) { itemList.add(t); } }
现在我们可以使用Decorator给List添加或者打印任何类型了,如代码清单3所示。
代码清单3
/** * * 类 名: Exp1<br/> * 描 述: 泛型最基本使用<br/> * 作 者: jiaan.gja<br/> * 创 建: 2015年8月13日<br/> * * 历 史: (版本) 作者 时间 注释 */ class Exp1 { public static void main(String[] args) { Decorator<Auction> decoratorA = new Decorator<Auction>(); List<Auction> listA = new ArrayList<Auction>(); Auction auctionOne = new Auction("auctionOne"); Auction auctionTwo = new Auction("auctionTwo"); decoratorA.addDecorate(listA, auctionOne); decoratorA.addDecorate(listA, auctionTwo); decoratorA.doDecorate(listA); Decorator<Table> decoratorB = new Decorator<Table>(); List<Table> listB = new ArrayList<Table>(); Table tableOne = new Table("tableOne", 10); Table tableTwo = new Table("tableTwo", 20); decoratorB.addDecorate(listB, tableOne); decoratorB.addDecorate(listB, tableTwo); decoratorB.doDecorate(listB); Decorator<Service> decoratorC = new Decorator<Service>(); List<Service> listC = new ArrayList<Service>(); Service serviceOne = new Service("serviceOne", "methodOne"); Service serviceTwo = new Service("serviceTwo", "methodTwo"); decoratorC.addDecorate(listC, serviceOne); decoratorC.addDecorate(listC, serviceTwo); decoratorC.doDecorate(listC); } }
遗留问题
如果想要Auction用于Decorator,必须要声明Decorator<Auction>;Service用于Decorator,也必须声明Decorator<Service>。由于Table是Auction的子类型,我们自然想将Table也能用于Decorator<Auction>,就像下面这样:decoratorA.doDecorate(listB);
listB的泛型Table的确是decoratorA的泛型Auction的子类型,但是编译器会报错,说明不允许这种语法。
如何解决这个问题?请看下一篇《Java泛型的协变》
相关文章推荐
- eclipse总是自动跳到ThreadPoolExecutor.java
- spring整合cxf方式发布的rest webservice,调用接口
- Eclipse存console的log
- java简单实现webservice接口
- 安卓开发环境的搭建和解决在Eclipse新建安卓5.1工程不能自动生成R文件的问题
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
- eclipse安装ADT和SDK插件
- Java 利用 BeanUtils进行遇见的错误
- Java利用 AES/ECB/PKCS5Padding 算法加解密
- Java GC日志分析
- java截取日期范围并计算相差月数
- struts升级到2.3出现各种问题
- 分布式任务调度——quartz + spring + 数据库
- Java - Encapsulation封装(面向对象1-封装)
- Java并发编程:线程池的使用
- 什么时候使用接口?什么时候使用抽象?选择Java接口还是抽象类
- JAVA项目性能测试项目实战视频教程
- springmvc传递参数
- Java bit位提取
- Spring Boot 在Gradle构建中使用Log4j日志