##前言
这两天在看以前写的ssh项目时,遇到一个问题就是封装的BaseDaoImpl抽象类,构造方法里面是这样写的
Class<T> clazz;
public BaseDaoImpl(){
ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass();
clazz = (Class<T>)pt.getActualTypeArguments()[0];
}
当时看到还真不知道里面到底是什么意思,记得以前写时是参考网上写的 ,于是我只有再去网上找答案了,一番搜索终于知道了。
##ParameterizedType
- getClass().getGenericSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type,然后将其转换ParameterizedType。 - getActualTypeArguments()
返回表示此类型实际类型参数的 Type 对象的数组。[0]就是这个数组中第一个了。简而言之就是获得超类的泛型参数的实际类型。
看意思可能不是很懂,我们直接看例子
package com.chen.demo;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
class param<T1, T2> {
class A {}
class B extends A {}
private Class<T1> entityClass;
public param (){
Type type = getClass().getGenericSuperclass();
System.out.println("getClass() == " + getClass());
System.out.println("type = " + type);
Type trueType = ((ParameterizedType)type).getActualTypeArguments()[0];
System.out.println("trueType1 = " + trueType);
trueType = ((ParameterizedType)type).getActualTypeArguments()[1];
System.out.println("trueType2 = " + trueType);
this.entityClass = (Class<T1>)trueType;
System.out.println("entityClass = " + entityClass);
B t = new B();
type = t.getClass().getGenericSuperclass();
System.out.println("A is B's super class :" + ((ParameterizedType)type).getActualTypeArguments().length);
}
}
public class ClassDemo extends param<MyClass, MyInvoke>{
public static void main(String[] args) {
ClassDemo classDemo = new ClassDemo();
}
}
package com.chen.demo;
public class MyClass {
}
package com.chen.demo;
public class MyInvoke {
}
我们再看打印结果
getClass() == class com.chen.demo.ClassDemo
type = com.chen.demo.param<com.chen.demo.MyClass, com.chen.demo.MyInvoke>
trueType1 = class com.chen.demo.MyClass
trueType2 = class com.chen.demo.MyInvoke
entityClass = class com.chen.demo.MyInvoke
A is B's super class :0
从上面结果我们可以总结如下,通过ParameterizedType获取泛型参数Class类型,然后我们就可以通过Class干一系列事情了。。。。。
比如数据库基本CRUD的工具类,直接看工具代码如下:
public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
Class<T> clazz;
public BaseDaoImpl(){
//getClass().getGenericSuperclass()返回表示此 Class
//所表示的实体(类、接口、基本类型或 void)的直接超类的 Type
//然后将其转换ParameterizedType
//getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组
//[0]就是这个数组中第一个了。
ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass();
clazz = (Class<T>)pt.getActualTypeArguments()[0];
}
@Override
public void save(T entity) {
getHibernateTemplate().save(entity);
}
@Override
public void delete(Serializable id) {
getHibernateTemplate().delete(findObjectById(id));
}
@Override
public void update(T entity) {
getHibernateTemplate().update(entity);
}
@Override
public T findObjectById(Serializable id) {
return getHibernateTemplate().get(clazz, id);
}
@Override
public List<T> findObjects() {
Query query = (Query) getSession().createQuery("from " + clazz.getSimpleName());
return query.list();
}
@Override
public List<T> findObjects(QueryHelper queryHelper){
Query listQuery = getSession().createQuery(queryHelper.getHql());
List<Object> parameters = queryHelper.getParameters();
if(parameters != null){
for(int i = 0; i<parameters.size(); i++){
listQuery.setParameter(i, parameters.get(i));
}
}
return listQuery.list();
}
工具类用到了Spring的orm模块,其次我们最重用的就是可以通过ParameterizedType封装通用的CRUD工具类,在实际的项目中,我们让不同的业务模块继承至该工具类,然后就可以直接使用其CRUD方法了。
##参考