ParameterizedType获取java泛型参数类型

Posted 0 1 0 1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ParameterizedType获取java泛型参数类型相关的知识,希望对你有一定的参考价值。

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泛型参数类型的主要内容,如果未能解决你的问题,请参考以下文章

Java获取泛型 Class

GenericDAO 与 Guice,玩泛型和 ParameterizedType

java获取泛型class

如何在运行时获取泛型的类型

java 泛型对象能实例化吗T t=new T()

javajav 通过 反射 获取 泛型信息