打字猴:1.700448482e+09
1700448482 if(types.length>0&&types[0]instanceof Class){
1700448483
1700448484 //若有多个泛型参数,依据位置索引返回
1700448485
1700448486 return(Class)types[0];
1700448487
1700448488 }
1700448489
1700448490 }
1700448491
1700448492 return(Class)Object.class;
1700448493
1700448494 }
1700448495
1700448496 }
1700448497
1700448498 前面我们讲过,Java的泛型类型只存在于编译期,那为什么这个工具类可以取得运行期的泛型类型呢?那是因为该工具只支持继承的泛型类,如果是在Java编译时已经确定了泛型类的类型参数,那当然可以通过泛型获得了。例如有这样一个泛型类:
1700448499
1700448500 abstract class BaseDao<T>{
1700448501
1700448502 //获得T的运行期类型
1700448503
1700448504 private Class<T>clz=Utils.getGenricClassType(getClass());
1700448505
1700448506 //根据主键获得一条记录
1700448507
1700448508 public void get(long id){
1700448509
1700448510 session.get(clz, id);
1700448511
1700448512 }
1700448513
1700448514 }
1700448515
1700448516 //操作user表
1700448517
1700448518 class UserDao extends BaseDao<String>{
1700448519
1700448520 }
1700448521
1700448522 对于UserDao类,编译器编译时已经明确了其参数类型是String,因此可以通过反射的方式来获取其类型,这也是getGenricClassType方法使用的场景。
1700448523
1700448524 BaseDao和UserDao是ORM中的常客,BaseDao实现对数据库的基本操作,比如增删改查,而UserDao则是一个比较具体的数据库操作,其作用是对User表进行操作,如果BaseDao能够提供足够多的基本方法,比如单表的增删改查,那些与UserDao类似的BaseDao子类就可以省去大量的开发工作。但问题是持久层的session对象(这里模拟的是Hibernate Session)需要明确一个具体的类型才能操作,比如get查询,需要获得两个参数:实体类类型(用于确定映射的数据表)和主键,主键好办,问题是实体类类型怎么获得呢?
1700448525
1700448526 子类自行传递?麻烦,而且也容易产生错误。
1700448527
1700448528 读取配置问题?可行,但效率不高。
1700448529
1700448530 最好的办法就是父类泛型化,子类明确泛型参数,然后通过反射读取相应的类型即可,于是就有了我们代码中的clz变量:通过反射获得泛型类型。如此实现后,UserDao可以不用定义任何方法,继承过来的父类操作方法已经能满足基本需求了,这样代码结构清晰,可读性又好。我已将这种方式使用在多个项目中了,目前没有出现因为该反射引起的性能问题。
1700448531
[ 上一页 ]  [ :1.700448482e+09 ]  [ 下一页 ]