1. 程式人生 > >ParameterizedType獲取java泛型參數類型

ParameterizedType獲取java泛型參數類型

dao tail tps cin rap .net 轉換 argument eth

https://blog.csdn.net/qq_18242391/article/details/54251947

前言

這兩天在看以前寫的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方法了。

參考

http://blog.csdn.net/only_wan/article/details/52781817

另外一個例子

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 }

ParameterizedType獲取java泛型參數類型