打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
古月白狐 残空望月 万杯不醉 千月星痕 Java泛型的运用

Java泛型的运用

Java泛型的运用

说来惭愧,jdk1.6都快出来了,1.5的泛型还没怎么用过。顶多用用List<Person>搭配foreach语法来简化一些代码。前段时间发现在设计Base类的时候发现不用泛型就免不了Object的转型,相当不爽。前不久在江南白衣的blog上面看了获取T.class的方法,收益匪浅。

下面说几个泛型使用时注意的问题。

对于public void demo1(List<Object>list)这个接口,我可以这样使用吗?

List<Person> personList = new LinkedList<Person>();demo1(personList)

看上去PersonObject的子类,可以透明地向上转型,成功调用接口,其实不然。注意List<Object>List<Person>是两个平行的不同的参数类型,不存在任何的继承挂关系。那么如果我确实想设计一个通用的接口怎么办呢?可以设计成public void demo2(List<?> list)这样List<Teacher> List<Student>就都可以使用了。但是仔细想一想,这样的接口和public void demo3(List list)有什么区别吗?毫无区别。应为demo2这个接口中如果想对list中的元素进行处理,拿到手里的还是Object,免不了向下转型。对于Java语言来说"泛"不是问题,Object那是相当的泛.引入泛型的目的之一就是利用T来对类型进行收敛,简化语法的同时减少出错的肯能性.但现在又出现了向下转型,那?有什么意义吗?当然是有意义的.不过要引入一个新的语法.Public void demo4(List<? extends Person>),这样既保证List<Student>,List<Teacher>可以使用这个接口,又保证了接口中可以以Person这个基类进行统一操作.以上就是泛型使用的时候需要主义的问题.

 

下面说说泛型在框架设计时候的用处.

首先我有一个EntityBean(请不要和EJB2.1那个UGLYEntityBean作任何联想)作为POJO的统一基类,里面完成了一些toXML,toString,equals,hashCode,copyProperties,clone,getId等统一方法.我利用Dozer来在写clone方法时,发现返回Object类型.那么子类在使用的时候就不许强制转型,客户端使用不是很爽.

用了泛型就能很容易解决问题

public class Entity<T> {

    public T clone()

    {

       return this.clone();

    }

}

 

public class NewsBean extends Entity<NewsBean>{

    public static void main(String args[])

    {

       NewsBean nb1 = new NewsBean();

       NewsBean nb2 = nb1.clone();

    }

}

 

当然不用泛型也能解决这个问题,就是在 NewsBean类里面写public NewsBean clone()方法,然后在里面调用基类的clone方法.这是采用窄化返回类型的方法来对基类的返回类型进行收敛.

 

下面说说取得类型Tclass的方法,用BaseHibernateDao来做例子

import java.lang.reflect.ParameterizedType;

 

public class BaseHibernateEntityDao<T> {

    private Class<T> entityClass;

 

    public BaseHibernateEntityDao() {

       entityClass = (Class<T>) ((ParameterizedType) getClass()

    .getGenericSuperclass()).getActualTypeArguments()[0];

    }

 

    public Class<T> getEntityClass() {

       return entityClass;

    }

 

    public T getEntity() throws InstantiationException, IllegalAccessException {

       return (T) entityClass.newInstance();

    }

}

 

class PersonDao extends BaseHibernateEntityDao<Person> {

    public static void main(String args[])

    {

       PersonDao personDao = new PersonDao();

       System.out.println(personDao.getEntityClass());

    }

}

最后打印的结果是class Person

 

子类什么都没有干,没有做任何的覆写,只是在定义的时候为所继承的父类确定了类型.着重看蓝色的那句话.这就是取得T class的方法.最后之所以用[0]是因为基类只有一个类型T,如果有<T,E>那么这个Type数组也就会有两个元素了.

 

最后请记住一点,虽然一般来说List<T> List都是可行的,也就是说泛型是透明的,如果你不指定T就默认类中用T定义的属性都是Object类型的.但是在这个例子中,必须为BaseHibernateEntityDao指定类型,否则就会出错,通不过ParameterizedType转型这一步.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
mockito简单教程
private关键字的概述和特点
Spring边学习边总结
JPA整合spring具体实现方法
Spring.Net的IOC入门
day11(运算符)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服