转载自  Java通过Class的对象来获取泛型的class示例

在使用spring的JdbcTemplate实现DAO的时候,经常会用到一个类ParameterizedBeanPropertyRowMapper。它的静态方法newInstance()接受一个Class类型的参数,用于将ResultSet中的属性映射到传入的这个Class类型的Bean对象中,再组成列表返回。
 
如果要想把这个DAO做成泛型的,就必须要知道Class的类型。但是直接写成T.class显然是不行的。从网上查了不少资料,结果只有一个,由于Java的泛型实现使用了“擦拭法”(具体细节没深究,呵呵),导致Java的泛型不能直接获取到自身的声明的泛型类型。
 
不过从江南白衣的blog文章里搜到了有用的东西:使用反射来获得“T.class”。
原文地址:http://www.blogjava.net/calvin/archive/2009/12/10/43830.html
 
主要用到的是这么一句:
[c-sharp] view plain copy
Class <T> entityClass = (Class <T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];   
 
我查询了Java API,在Class类中有这么两个方法: getGenericInterfaces()和getGenericSuperclass()
先来看看这两个方法都是干什么用的:
1. public Type getGenericSuperclass()
用来返回表示当前Class 所表示的实体(类、接口、基本类型或 void)的直接超类的Type。如果这个直接超类是参数化类型的,则返回的Type对象必须明确反映在源代码中声明时使用的类型。比如:

package com.mot.hyena.test;
import java.lang.reflect.ParameterizedType;
public class GT1 extends GT2<Integer>{  public static void main(String[] args) {  System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass()));  }
}  

则输出结果即为:com.mot.hyena.test.GT2<java.lang.Integer>
 
如果此Class代表的是Object 类、接口、基本类型或 void,则返回 null。。如果此对象表示一个数组类,则返回表示 Object 类的 Class 对象。
 
2. public Type[] getGenericInterfaces()
与上面那个方法类似,只不过Java的类可以实现多个接口,所以返回的Type必须用数组来存储。
 
以上两个方法返回的都是Type对象或数组,在我们的这个话题中,Class都是代表的参数化类型,因此可以将Type对象Cast成ParameterizedType对象。而 ParameterizedType对象有一个方法, getActualTypeArguments()。
public Type[] getActualTypeArguments()

用来返回一个Type对象数组,这个数组代表着这个Type声明中实际使用的类型。接着使用上面的例子:

package com.mot.hyena.test;
import java.lang.reflect.ParameterizedType;
public class GT1 extends GT2<Integer>{  public static void main(String[] args) {  System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass()).getActualTypeArguments()[0]);  }
}  

这次的显示结果将是:class java.lang.Integer
 
因此,我们可以通过继承+反射的方法,来的到T.class。
 
需要说明的是,江南白衣使用的方法是将关键语句
Class < T >  entityClass  =  (Class < T > ) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[ 0 ];
放在了超类,也就是声明泛型的那个类的构造方法中。这样一来,子类在继承具有泛型的超类时,会自动调用超类的构造方法。在此超类的构造方法中,调用的getClass返回的是子类的Class类型(与通常的重写机制有悖,呵呵,有待深究,但测试结果确是如此),则在子类中就无需再显式地使用 getGenericInterfaces()和getGenericSuperclass()等方法了。

接着,再使用(Class<T>)对 getActualTypeArguments()返回的元素做casting,即可得到所谓的T.class。

完整示例:

Java通过Class的对象来获取泛型的class示例

[java] view plaincopy
  1. /**
  2. * 创建一个Class的对象来获取泛型的class
  3. */
  4. private Class<T> clz;
  5. @SuppressWarnings("unchecked")
  6. public Class<T> getClz(){
  7. if (clz==null) {
  8. clz=(Class<T>)(((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
  9. }
  10. return clz;
  11. }

此方法一般在模板方法中经常用到,因此做一个笔记!

Java通过Class的对象来获取泛型的class示例相关推荐

  1. java 获取泛型的type,如何获取泛型的Type类型

    开发中很多时候都遇到或使用到泛型.例如在json转换成bean对象或其他对象,而对象中存在泛型,这时候需要用到TypeToken. Type:是java里的 java.lang.reflect.Typ ...

  2. java 泛型反射_Java使用反射来获取泛型信息示例

    本文实例讲述了Java使用反射来获取泛型信息.分享给大家供大家参考,具体如下: 一 点睛 获得了Field对象后,就可以很容易地获得该Field的数据类型,即使用如下代码即可获得指定Field的类型: ...

  3. java 反射和泛型-反射来获取泛型信息

    通过指定对应的Class对象,程序可以获得该类里面所有的Field,不管该Field使用private 方法public.获得Field对象后都可以使用getType()来获取其类型. Class&l ...

  4. java 获取泛型_聊聊Java泛型擦除那些事

    >版权申明]非商业目的注明出处可自由转载 博文地址:https://blog.csdn.net/ShuSheng0007/article/details/89789849 出自:shushen ...

  5. java反射获取泛型_如何通过Java反射获取泛型类型信息

    前言 关于Java泛型,很多人都有一个误解,认为Java代码在编译时会擦除泛型的类型,从而在运行时导致没法访问其类型,这其实并不完全正确,因为有一部分泛型信息是可以在运行时动态获取的,这部分信息基本能 ...

  6. java 运行时获取泛型真实类型

    前情提要 本文章用于运行时获取泛型的具体类型,有一些情况下可以获取到真实类型,有一些情况下获取不到的情况. Class 类的两个方法 /*** Returns the {@code Class} re ...

  7. 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理

    反射机制概述.获取Class实例.类的加载与ClassLoader的理解.创建运行时类的对象.获取运行时类的完整结构.调用运行时类的指定结构.动态代理 反射 1 Java反射机制概述 1.1 Java ...

  8. Java反射之从对象获取值

    我们在开发的过程中,可能会遇到需要动态地通过字符串获取某个值,该值来自于某个对象. 利用反射可以,方便获取.该类可提取为工具类,供众多类调用. getValueFormObject方法就是从Objec ...

  9. Java获取泛型T的类型 T.class

    import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;public class Main{public s ...

最新文章

  1. linux查看msf安装目录,linux系统安装msf的过程详解
  2. 为ListBox添加水平滚动条
  3. mysql数据库写入数据的语法_mysql数据库插入数据语法
  4. Dart基础第1篇:Dart环境搭建、Dart开发工具
  5. Java程序员从笨鸟到菜鸟之(五十)细谈Hibernate(一)hibernate基本概念和体系结构...
  6. [含论文+答辩PPT+任务书+中期检查表+源码等]基于ssm的NBA球队管理系统
  7. Just Speak 论文精读
  8. 2021第一届网刃杯网络安全大赛-签到题
  9. 电脑怎么打出冒号符号_电脑键盘怎么打出冒号符号
  10. 【路由篇】01. 电脑远程访问小米路由器硬盘文件
  11. OpenCV3.4.x移植到嵌入式ARM板
  12. java动态规划凑硬币问题_动态规划 凑硬币问题
  13. 蚌埠学院计算机操作系统题库,蚌埠学院电子教务登录
  14. 计算机显示器窗口成灰色,电脑显示器只显示灰色背光
  15. 【GD32F310开发板试用】Contiki-NG在GD32F310的移植
  16. python双击py一闪_python双击py一闪 python编程
  17. 刘世光 计算机图像学,刘世光
  18. 我替一位仁兄改的n进制数相加的问题
  19. 提现业务流程介绍与设计
  20. 集群并行效率测试软件,并行集群系统的Linpack性能测试分析

热门文章

  1. 《C++ Primer》14.2.1节练习
  2. 《C++ Primer》7.2节练习
  3. Pseudoprime numbers POJ - 3641(快速幂+判素数)
  4. 题目 1885: [蓝桥杯][2017年第八届真题]分巧克力+二分
  5. 数据结构与算法--位运算
  6. python分布式存储文件_python如何分布式存储文件的方法
  7. 常系数齐次线性递推学习笔记
  8. Desert King POJ - 2728
  9. 牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案
  10. 【每日一题】8月10日题目精讲—排座椅