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
- 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("B is A's super class :" + ((ParameterizedType)type).getActualTypeArguments().length);
- }
- }
- class MyClass {
- }
- class MyInvoke {
- }
- public class ClassDemo extends param<MyClass, MyInvoke>{
- public static void main(String[] args) {
- ClassDemo classDemo = new ClassDemo();
- }
- }
我们再看打印结果:
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 的工具类, 直接看工具代码如下:
- 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 方法了.
参考
http://blog.csdn.net/only_wan/article/details/52781817
另外一个例子
- MyInterface.java
- package com.chen.demo;
- public interface MyInterface<T,V> {
- void onSuccess(T data);
- }
- MySuperClass.java
- package com.chen.demo;
- public abstract class MySuperClass<T,V> {
- public abstract void onSuccess(T data);
- }
- Student.java
- package com.chen.demo;
- public class Student {
- }
- ClassDemo.java
- package com.chen.demo;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- // 利用 ParameterizedType 获取 java 泛型的参数类型
- public class ClassDemo {
- public static void main(String[] args) {
- classTest();
- interfaceTest();
- }
- private static void classTest() {
- MySuperClass<Student, String> mySuperClass = new MySuperClass<Student, String>() {
- @Override
- public void onSuccess(Student data) {
- }
- };
- //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体的直接超类的 Type
- ParameterizedType type = (ParameterizedType) mySuperClass.getClass().getGenericSuperclass();
- sysoType(type);
- }
- private static void interfaceTest() {
- MyInterface<Student, String> myInterface = new MyInterface<Student, String>() {
- @Override
- public void onSuccess(Student data) {
- }
- };
- ParameterizedType type = (ParameterizedType) myInterface.getClass().getGenericInterfaces()[0];
- sysoType(type);
- }
- private static void sysoType(ParameterizedType type) {
- /*com.chen.demo.MySuperClass<com.chen.demo.Student, java.lang.String>
- class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
- class com.chen.demo.Student
- class java.lang.Class
- class java.lang.String
- class java.lang.Class
- com.chen.demo.MyInterface<com.chen.demo.Student, java.lang.String>
- class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
- class com.chen.demo.Student
- class java.lang.Class
- class java.lang.String
- class java.lang.Class*/
- System.out.println(type + "\n" + type.getClass());
- // 返回表示此类型实际类型参数的 Type 对象的数组, 泛型的参数可能有多个, 我们需要哪个就取哪个
- Type[] targets = type.getActualTypeArguments();
- for (int i = 0; i < targets.length; i++) {
- System.out.println(targets[i] + "\n" + targets[i].getClass());
- }
- }
- }
来源: http://www.bubuko.com/infodetail-2562421.html