java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()
引言
public class HasNoFanxin {
public static Object newInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class clz = Class.forName(className);
return clz.newInstance();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String str = (String) newInstance("java.lang.Date");
System.out.println(str);
}
}
如下使用泛型,输入有误的话编译时就会报异常,提前提示错误(编译时就自动推断了泛型的真实类型)
public class HasFanxin {
public static <T> T newInstance(Class<T> clz) throws InstantiationException, IllegalAccessException {
return clz.newInstance();
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Date str = newInstance(Date.class); // 这里传入什么类型,传出就必须是什么类型,如果写成了String str = ... 就会编译报错
}
}
通过反射获取变量、方法形参的泛型类型
以获取类变量泛型为例
- Type gType = f.getGenericType();
- gtype instanceof ParameterizedType
- ParameterizedType ptype = (ParameterizedType) type
getRawType() 返回没有泛型信息的原始类型。
getActualTypeArguments(): 返回泛型参数的类型Type 数组。
- Type[] types = ptype.getActualTypeArguments();
获取方法参数的泛型,可以通过反射方法的参数本身Parameter反射对象,再通过反射对象的getParameterizedType()方法获取本参数的类型的Type对象,进行如上第 2.步骤及以后
或者
通过反射的方法Method对象,通过Method对象getGenericParameterTypes()方法,直接获取所有形参的类型组成的Type数组,再循环经过第 2.步骤及以后
package com.zmd.fanxingfanshe; import java.lang.reflect.*;
import java.util.List;
import java.util.Map; /**
* @ClassName FanxingTest
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/17.
*/
public class FanxingTest {
//带泛型的属性(类变量或实例变量)
private Map<String, Integer> data;
private String string;
//定义带泛型的方法
private static void fanxingMethod(Map<String, Integer> users, String list){ }
//测试获取泛型
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
//获取类
Class<FanxingTest> cls = FanxingTest.class;
//获取类变量
Field dataField = cls.getDeclaredField("data");
System.out.println("=========获取类变量泛型类型==============="); //输出data的类型interface java.util.Map
System.out.println("data 的类型:" + dataField.getType()); //获取对应的带泛型类型
Type gtype = dataField.getGenericType();
System.out.println("参数类型:" + gtype); //java.util.Map<java.lang.String, java.lang.Integer>
if (gtype instanceof ParameterizedType){
//将Type对象强制类型转换为ParameterizedType对象
ParameterizedType ptype = (ParameterizedType) gtype;
System.out.println(ptype);
System.out.println(gtype + "的原始类型:" + ptype.getRawType());
//获取对应的泛型的类型
Type[] tTypes = ptype.getActualTypeArguments();
for (Type tType : tTypes){
System.out.println(tType);
}
} /**
* 获取方法形参的泛型
*/
System.out.println("=========通过反射获取方法,再通过方法getGenericParameterTypes获取形参泛型类型:===============");
//输入方法名和参数的类列表,获取具体方法的反射
Method fxMethod = cls.getDeclaredMethod("fanxingMethod", Map.class, String.class);
//设置private类型方法可访问
fxMethod.setAccessible(true);
//获取所有参数类型列表
Type[] parameterTypes = fxMethod.getGenericParameterTypes();
for (Type type: parameterTypes){
//当前参数类型
System.out.println("参数类型" + type);
if (type instanceof ParameterizedType){
ParameterizedType ptype = (ParameterizedType) type;
//原始类型
System.out.println("参数原始类型:" + ptype.getRawType());
//获取对应泛型的类型
Type[] types = ptype.getActualTypeArguments();
for (Type tType: types){
System.out.println(tType);
}
}
} //通过反射参数自身反射泛型
System.out.println("=========通过反射获取方法,再通过方法获取参数反射,再通过参数.getParameterizedType()获取形参泛型类型:===============");
Parameter[] parameters = fxMethod.getParameters();
for (Parameter parameter : parameters){
System.out.println("获取到参数:" + parameter.getName());
Type type = parameter.getParameterizedType();
System.out.println(parameter.getName() + "参数的类型:" + type);
if (type instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) type;
System.out.println(parameter.getName() + "参数的原始类型:"+ parameterizedType.getRawType());
Type[] types = parameterizedType.getActualTypeArguments();
for (Type type1 : types){
System.out.println(type1);
}
}
}
}
}
输出
=========获取类变量泛型类型===============
data 的类型:interface java.util.Map
参数类型:java.util.Map<java.lang.String, java.lang.Integer>
java.util.Map<java.lang.String, java.lang.Integer>
java.util.Map<java.lang.String, java.lang.Integer>的原始类型:interface java.util.Map
class java.lang.String
class java.lang.Integer
=========通过反射获取方法,再通过方法getGenericParameterTypes获取形参泛型类型:===============
参数类型java.util.Map<java.lang.String, java.lang.Integer>
参数原始类型:interface java.util.Map
class java.lang.String
class java.lang.Integer
参数类型class java.lang.String
=========通过反射获取方法,再通过方法获取参数反射,再通过参数.getParameterizedType()获取形参泛型类型:===============
获取到参数:arg0
arg0参数的类型:java.util.Map<java.lang.String, java.lang.Integer>
arg0参数的原始类型:interface java.util.Map
class java.lang.String
class java.lang.Integer
获取到参数:arg1
arg1参数的类型:class java.lang.String Process finished with exit code 0
java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()的更多相关文章
- Java编程基础-反射
一.java反射 1.反射:动态获取类的信息,以及动态调用对象的方法的功能.可以理解为动态看透类的能力. 2.主要功能:在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意 ...
- java 反射和泛型-反射来获取泛型信息
通过指定对应的Class对象,程序可以获得该类里面所有的Field,不管该Field使用private 方法public.获得Field对象后都可以使用getType()来获取其类型. Class&l ...
- JAVA基础_反射获取泛型参数类型
我经常会想获取参数的实际类型,在Hibernate中就利用的这一点. domain: Person.java public class Person { // 编号 private Long id; ...
- Java框架基础——反射(reflect)
一.Class类的使用 1)在面向对象(oop)的世界里,万事万物皆对象. 在Java中,包括基本的数据类型,都是对象. Class c = int.class;//int 的类类型 那就是说: 类是 ...
- Java 高级基础——反射
Java 高级基础--反射 反射的意义:Java 强类型语言,但是我们在运行时有了解.修改信息的需求,包括类信息.成员信息以及数组信息. 基本类型与引用类型 基本类型,(固定的 8 种) 整数:byt ...
- Java编程基础-面向对象(中)
本章承接Java编程基础-面向对象(上)一文. 一.static关键字 在java中,定义了一个static关键字,它用于修饰类的成员,如成员变量.成员方法以及代码块等,被static修饰的成员具备一 ...
- Java入门——(1)Java编程基础
Java入门--(1)Java编程基础 第二章 Java编程基础 JAVA 代码的基本格式: 修饰符 class 类名{ 程序代码 } 2.1关键字:赋予了特殊含义的单词. 2.2标识符: ...
- Java开发知识之Java编程基础
Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...
- 反射方式,获取出集合ArrayList类的class文件对象
/* * 定义集合类,泛型String * 要求向集合中添加Integer类型 * * 反射方式,获取出集合ArrayList类的class文件对象 * 通过class文件对象,调用add方法 * * ...
随机推荐
- Atcoder Regular Contest 123 题解
u1s1 我是真的不知道为什么现场这么多人切了 D,感觉 D 对思维要求显然要高于其他 300+ 人切掉的 D 吧(也有可能是 Atc 用户整体水平提升了?) A 开 幕 雷 击(这题似乎 wjz 交 ...
- Go语言核心36讲(Go语言实战与应用二十)--学习笔记
42 | bufio包中的数据类型 (上) 今天,我们来讲另一个与 I/O 操作强相关的代码包bufio.bufio是"buffered I/O"的缩写.顾名思义,这个代码包中的程 ...
- Python使用print打印时,展示内容不换行
原理 Python的print()函数中参数end='' 默认为\n,所以会自动换行; 默认的print()函数: print(end='\n') 方案 Python 2: 在print语句的末尾加上 ...
- Xpath解析库的使用
### Xpath常用规则 ## nodename 选取此节点的所有子节点 ## / 从当前节点选取直接子节点 ## // 从当前节点选取子孙节点 ## . 选取当前节点 ## .. 选取当前节点的父 ...
- Excel-满足指定条件并且包含数字的单元格数目,DCOUNT()
DCOUNT函数 函数名称:DCOUNT 主要功能:返回数据库或列表的列中满足指定条件并且包含数字的单元格数目. 使用格式:DCOUNT(database,field,criteria) 参数说明:D ...
- 工作学习2-gcc升级引发的崩溃
分享一下调查gcc 8.0下,函数漏写返回值崩溃问题,调查记录. 现在新的硬件,基本操作系统都是redhat 8.0,升级后测试时,发现了一个崩溃问题,记录一下. ================== ...
- 巩固javaweb第三天
巩固内容: HTML 标题 HTML 标题(Heading)是通过<h1> - <h6> 标签来定义的. HTML 段落 HTML 段落是通过标签 <p> 来定义的 ...
- Learning Spark中文版--第五章--加载保存数据(1)
开发工程师和数据科学家都会受益于本章的部分内容.工程师可能希望探索更多的输出格式,看看有没有一些适合他们下游用户的格式.数据科学家可能会更关注他们已经使用的数据格式. Motivation 我 ...
- Docker学习(二)——Docker容器使用
Docker容器使用 1.Docker客户端 命令docker可以查看到Docker客户端的所有命令选项. 命令docker command --help更深入的了解指定的Do ...
- [转]C++中const的使用
原文链接:http://www.cnblogs.com/xudong-bupt/p/3509567.html 平时在写C++代码的时候不怎么注重const的使用,长久以来就把const的用法忘记了 写 ...