Java反射获取泛型类型
本文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613
在Java反射技术的应用中,取得一个类的成员、方法和构造函数相对比较容易,但是要想取得其中包含的泛型类型则相对困难一些。先看一个简单的例子,然后详细说明每个步骤的作用。
public class Demo {
private List<Integer> list1;
private List<Set<Integer>> listSet;
public Set<String> fun1(Map<Integer, String> map){return null;}
public static void getFieldGenericType() {
try {
Class clazz = Demo.class;
Field field = clazz.getDeclaredField("list1");
Type type = field.getGenericType(); //取得field的type
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type; //强转成具体的实现类
Type[] genericTypes = parameterizedType.getActualTypeArguments(); //取得包含的泛型类型
System.out.println(genericTypes[0]);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
getFieldGenericType();
}
}
上面的代码可以正确的打印出Demo类的成员list1的泛型类型Integer。代码中的第一步通过getGenericType()方法获得一个Type类型。这个Type其实就代表了List<Interger>,Type的实现类可以是Class,也可以是ParameterizedTypeImpl。如果field的类型是泛型则通过getGenericType()取到的就是ParameterizedTypeImpl,如果是普通的类则取到的就是Class。我们在编译器取到的Class是没有泛型信息的,通过field的getType方法取到的信息只能是List,而不是List<Interger>,所以我们才用上面的方法获取泛型的类型;第二步将Type强转成了ParameterizedTypeImpl类型,这里偷了个懒,因为知道真实的类型所以没有判断type的具体实现类,开发时千万不能这样写;第四步从ParameterizedTypeImpl中取得到了所有的泛型类型。ParameterizedTypeImpl也就是参数化的type,我们要获得的泛型类型相当于type的参数,有几个泛型类型,则getActualTypeArguments()会返回几个Type参数。
刚才说到Class是Type的子类,而通过getActualTypeArguments()获取到的又是一个Type数组,好像陷入到了无限的循环当中。没错,在真实的代码中也确实存在着泛型类型的嵌套使用,例如上面代码中的第二个域listSet。有了刚才的基础,获取多少层的嵌套泛型也可以解析出来。解析listSet中泛型信息的代码如下:
public static void getFieldGenericType1() {
try {
Class clazz = Demo.class;
Field field = clazz.getDeclaredField("listSet");
Type type = field.getGenericType(); //取得field的type
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type; //强转成具体的实现类
Type[] genericTypes = parameterizedType.getActualTypeArguments(); //取得包含的泛型类型
ParameterizedTypeImpl setType = (ParameterizedTypeImpl) genericTypes[0];//再次将代表Set<Integer>的Type强转成ParameterizedTypeImpl
Type[] setTypeArguments = setType.getActualTypeArguments();
System.out.println(setTypeArguments[0]);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
同样的道理,获取方法中的泛型信息也不在话下
public static void getMethodGenericType() {
try {
Class clazz = Demo.class;
Method method = clazz.getMethod("fun1", Map.class);
Type type = method.getGenericReturnType();
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type;
Type[] genericTypes = parameterizedType.getActualTypeArguments();
System.out.println("return generic type " + genericTypes[0]);
Type mapType = method.getGenericParameterTypes()[0];
ParameterizedTypeImpl mapParamType = (ParameterizedTypeImpl) mapType;//再次将代表Set<Integer>的Type强转成ParameterizedTypeImpl
Type[] mapArgs = mapParamType.getActualTypeArguments();
System.out.println("method param first generic type " + mapArgs[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
上面展示了解析成员和方法中泛型信息的方法,但是对于一个普通的变量可以在运行期解析出他的泛型信息吗?答案是不可以的,因为对于一个普通的变量我们只能拿到的他的Class信息,而刚刚也已经说到Class是没有泛型信息的。如果要获取到泛型的信息,首先要获取到ParameterizedTypeImpl才可以。
————————————————
版权声明:本文为CSDN博主「hongxingxiaonan」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613
Java反射获取泛型类型的更多相关文章
- Java 反射 -- 获取泛型类型
先写一个类: public class Demo03 { public void test01(Map<String, User> map, List<User> list) ...
- Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果 ...
- Java反射获取class对象的三种方式,反射创建对象的两种方式
Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...
- java反射获取注解并拼接sql语句
先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...
- 关于java反射获取泛型
public class Test<T> { private final TypeToken<T> typeToken = new TypeToken<T>(get ...
- Java 反射获取私有方法
通常我们创建一个类时,它的私有方法在类外是不可见的,但是可以通过反射机制来获取调用.具体的反射机制的介绍大家自己百度. 所以反射可能会破坏我们的单例模式,当然解决方案也是有的,就是做个标记记录次数,第 ...
- java反射获取和设置实体类的属性值 递归所有父类
最近做一个通用数据操作接口,需要动态获取和设置实体类的属性值,为了通用实体做了多重继承,开始网上找到代码都不支持父类操作,只能自己搞一个工具类了,此工具类可以设置和获取所有父类属性,代码贴下面拿走不谢 ...
- java反射获取Object的属性和值
在看反射顺便做个笔记,目前知道的反射的Object都是要有对象的也就是实体Bean. import java.lang.reflect.Field; import java.util.ArrayLis ...
- java 反射获取字段为List类型中的泛型类型
在java编程时,经常会使用反射去处理对象,有时会需要知道List的泛型类型:示例操作如下 obj = pojo.newInstance(); // 首先得到pojo所定义的字段 Field[] fi ...
随机推荐
- SVN Log命令常用组合【转】
转自:https://blog.csdn.net/xuanwenchao/article/details/8875103 版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请 ...
- failed to map segment from shared object: Permission denied(error while loading shared libraries: libz.so.1)
centos 6.3 服务器重启后,sshd 竟然连接不上了,防火墙也没有限制,重启sshd 服务报以下错误: 于是到/lib64 目录下找,库文件并没有少,仔细想后面的报错信息是权限被拒绝了,百度了 ...
- pytest文档29-allure-pytest(最新最全,保证能搞成功!)
前言 之前写了个pytest的allure相关的教程,只是停留在环境搭建完成,后续一直没用,小编一直不喜欢这种花里胡哨的报告. 没办法,领导就喜欢这种,小伙伴们也喜欢,所以还是得把allure用起来, ...
- 初识V4L2(三)-------分析vivi.c 虚拟视频驱动
1.分配video_device结构体 2.设置 3.注册 video_register_device 分析vivi.c: vivi_init( )//入口函数 vivi_create_instan ...
- 2018710101021-王方-《面向对象(java)程序设计》第十一周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- Vue2.0个人记录的学习笔记【待续】
一.Vue实例对象 我们构造一个实例对象 需要new一个Vue var my = new Vue({ el:‘#app’ ,[ app是装载的位置] template: ‘<div>< ...
- python -m pip install --upgrade pip
升级pip后报错 TypeError: 'module' object is not callable 原因 存在两个版本的pip 先把原先版本的卸载了: python -m pip uninstal ...
- 【Spring IoC】依赖注入DI(四)
平常的Java开发中,程序员在某个类中需要依赖其它类的方法.通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由程 ...
- zzTensorflow技术内幕:
性能优势 TensorFlow在大规模分布式系统上的并行效率相当高,如下图所示: 图5:TensorFlow并发效率 在GPU数量小于16时,基本没有性能损耗,在50块的时候,可以获得80%的效率,也 ...
- zz 机器学习系统或者SysML&DL笔记
机器学习系统或者SysML&DL笔记(一) Oldpan 2019年5月12日 0条评论 971次阅读 1人点赞 在使用过TVM.TensorRT等优秀的机器学习编译优化系统以及Py ...