前言
这两天在看以前写的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]就是这个数组中第一个了。简而言之就是获得超类的泛型参数的实际类型。
看意思可能不是很懂,我们直接看例子:
ClassDemo.java
1 package com.chen.demo;
2
3 import java.lang.reflect.ParameterizedType;
4 import java.lang.reflect.Type;
5
6 class param<T1, T2> {
7
8 class A {}
9 class B extends A {}
10
11 private Class<T1> entityClass;
12 public param () {
13 Type type = getClass().getGenericSuperclass();
14 System.out.println("getClass() == " + getClass());
15 System.out.println("type = " + type);
16 Type trueType = ((ParameterizedType)type).getActualTypeArguments()[0];
17 System.out.println("trueType1 = " + trueType);
18 trueType = ((ParameterizedType)type).getActualTypeArguments()[1];
19 System.out.println("trueType2 = " + trueType);
20 this.entityClass = (Class<T1>)trueType;
21 System.out.println("entityClass = " + entityClass);
22
23 B t = new B();
24 type = t.getClass().getGenericSuperclass();
25
26 System.out.println("B is A's super class :" + ((ParameterizedType)type).getActualTypeArguments().length);
27 }
28 }
29
30 class MyClass {
31 }
32
33 class MyInvoke {
34 }
35
36 public class ClassDemo extends param<MyClass, MyInvoke>{
37 public static void main(String[] args) {
38 ClassDemo classDemo = new ClassDemo();
39 }
40 }
我们再看打印结果:
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
B is A's super class :0
从上面结果我们可以总结如下,通过ParameterizedType获取泛型参数Class类型,然后我们就可以通过Class干一系列事情了。。。。。
比如数据库基本CRUD的工具类,直接看工具代码如下:
1 public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
2
3 Class<T> clazz;
4
5 public BaseDaoImpl(){
6 //getClass().getGenericSuperclass()返回表示此 Class
7 //所表示的实体(类、接口、基本类型或 void)的直接超类的 Type
8 //然后将其转换ParameterizedType
9 //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组
10 //[0]就是这个数组中第一个了。
11
12 ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass();
13 clazz = (Class<T>)pt.getActualTypeArguments()[0];
14 }
15
16 @Override
17 public void save(T entity) {
18 getHibernateTemplate().save(entity);
19 }
20
21 @Override
22 public void delete(Serializable id) {
23 getHibernateTemplate().delete(findObjectById(id));
24 }
25
26 @Override
27 public void update(T entity) {
28 getHibernateTemplate().update(entity);
29 }
30
31 @Override
32 public T findObjectById(Serializable id) {
33 return getHibernateTemplate().get(clazz, id);
34 }
35
36 @Override
37 public List<T> findObjects() {
38 Query query = (Query) getSession().createQuery("from " + clazz.getSimpleName());
39 return query.list();
40 }
41
42 @Override
43 public List<T> findObjects(QueryHelper queryHelper){
44 Query listQuery = getSession().createQuery(queryHelper.getHql());
45 List<Object> parameters = queryHelper.getParameters();
46
47 if(parameters != null){
48 for(int i = 0; i<parameters.size(); i++){
49 listQuery.setParameter(i, parameters.get(i));
50 }
51 }
52 return listQuery.list();
53 }
工具类用到了Spring的orm模块,其次我们最重用的就是可以通过ParameterizedType封装通用的CRUD工具类,在实际的项目中,我们让不同的业务模块继承至该工具类,然后就可以直接使用其CRUD方法了。
另外一个例子
MyInterface.java
1 package com.chen.demo;
2
3 public interface MyInterface<T,V> {
4 void onSuccess(T data);
5 }
MySuperClass.java
1 package com.chen.demo;
2
3 public abstract class MySuperClass<T,V> {
4 public abstract void onSuccess(T data);
5 }
Student.java
1 package com.chen.demo;
2
3 public class Student {
4
5 }
ClassDemo.java
1 package com.chen.demo;
2
3 import java.lang.reflect.ParameterizedType;
4 import java.lang.reflect.Type;
5
6 //利用ParameterizedType获取java泛型的参数类型
7
8 public class ClassDemo {
9 public static void main(String[] args) {
10 classTest();
11 interfaceTest();
12 }
13
14 private static void classTest() {
15 MySuperClass<Student, String> mySuperClass = new MySuperClass<Student, String>() {
16 @Override
17 public void onSuccess(Student data) {
18 }
19 };
20 //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体的直接超类的 Type
21 ParameterizedType type = (ParameterizedType) mySuperClass.getClass().getGenericSuperclass();
22 sysoType(type);
23 }
24
25 private static void interfaceTest() {
26 MyInterface<Student, String> myInterface = new MyInterface<Student, String>() {
27 @Override
28 public void onSuccess(Student data) {
29 }
30 };
31 ParameterizedType type = (ParameterizedType) myInterface.getClass().getGenericInterfaces()[0];
32 sysoType(type);
33 }
34
35 private static void sysoType(ParameterizedType type) {
36 /*com.chen.demo.MySuperClass<com.chen.demo.Student, java.lang.String>
37 class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
38 class com.chen.demo.Student
39 class java.lang.Class
40 class java.lang.String
41 class java.lang.Class
42
43 com.chen.demo.MyInterface<com.chen.demo.Student, java.lang.String>
44 class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
45 class com.chen.demo.Student
46 class java.lang.Class
47 class java.lang.String
48 class java.lang.Class*/
49 System.out.println(type + "\n" + type.getClass());
50 //返回表示此类型实际类型参数的 Type 对象的数组,泛型的参数可能有多个,我们需要哪个就取哪个
51 Type[] targets = type.getActualTypeArguments();
52 for (int i = 0; i < targets.length; i++) {
53 System.out.println(targets[i] + "\n" + targets[i].getClass());
54 }
55 }
56 }