java编程基础反射⽅式获取泛型的类型
引⾔
⾃从JDK5以后,Java Class类增加了泛型功能,从⽽允许使⽤泛型来限制Class类,例如,String.class的类型实际上是 Class 如果 Class 对应的类暂时未知,则使 Class<?>。通过在反射中使⽤泛型,可以避免使⽤反射⽣成的对象需要强制类型转换。
泛型作⽤对⽐:
如下⽰例没有使⽤泛型时,编译不报错,运⾏时报错强制转换异常
public class HasNoFanxin {
public static Object newInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class clz = Class.forName(className);
wInstance();
}
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
{
wInstance();
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Date str = newInstance(Date.class); // 这⾥传⼊什么类型,传出就必须是什么类型,如果写成了String str = ... 就会编译报错
}
}
通过反射获取变量、⽅法形参的泛型类型
以获取类变量泛型为例
前提:
通过反射获取类对应的成员变量Field
获取步骤:
1. 获得成员变量的类型
Type gType = f.getGenericType();
2. 判断类型是否为带泛型的类型
gtype instanceof ParameterizedType
当代水墨3. 将判断为待泛型的Type对象强制转换为ParameterizedType对象,(ParameterizedType代表被参数化的类型:也就是增加了泛型限制的类型)
ParameterizedType ptype = (ParameterizedType) type
4.通过强制转换后的ParameterizedType带泛型对象获取泛型的类型
getRawType() 返回没有泛型信息的原始类型。
getActualTypeArguments(): 返回泛型参数的类型Type 数组。
Type[] types = ActualTypeArguments();
获取⽅法参数的泛型,可以通过反射⽅法的参数本⾝Parameter反射对象,再通过反射对象的getParameterizedType()⽅法获取本参数的类型的Type对象,进⾏如上第 2.步骤及以后
或者
通过反射的⽅法Method对象,通过Method对象getGenericParameterTypes()⽅法,直接获取所有形参的类型组成的Type数组,再循环经过第 2.步骤及以后
d.fanxingfanshe;
关于运动会的广播稿import flect.*;
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> urs, String list){
}
/
/测试获取泛型
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
//获取类
Class<FanxingTest> cls = FanxingTest.class;
//获取类变量
Field dataField = DeclaredField("data");
System.out.println("=========获取类变量泛型类型===============");
//输出data的类型interface java.util.Map
System.out.println("data 的类型:" + Type());
//获取对应的带泛型类型
Type gtype = GenericType();
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 + "的原始类型:" + RawType());
//获取对应的泛型的类型
Type[] tTypes = ActualTypeArguments();
for (Type tType : tTypes){
System.out.println(tType);
}
}
/**
* 获取⽅法形参的泛型
*/
System.out.println("=========通过反射获取⽅法,再通过⽅法getGenericParameterTypes获取形参泛型类型:===============");
//输⼊⽅法名和参数的类列表,获取具体⽅法的反射
Method fxMethod = DeclaredMethod("fanxingMethod", Map.class, String.class);
//设置private类型⽅法可访问
fxMethod.tAccessible(true);
//获取所有参数类型列表
Type[] parameterTypes = GenericParameterTypes();
for (Type type: parameterTypes){
//当前参数类型
System.out.println("参数类型" + type);
if (type instanceof ParameterizedType){
ParameterizedType ptype = (ParameterizedType) type;
//原始类型
System.out.println("参数原始类型:" + RawType());
//获取对应泛型的类型
Type[] types = ActualTypeArguments();
for (Type tType: types){
System.out.println(tType);
}
}
}
//通过反射参数⾃⾝反射泛型
System.out.println("=========通过反射获取⽅法,再通过⽅法获取参数反射,再通过参数.getParameterizedType()获取形参泛型类型:==============="); Parameter[] parameters = Parameters();
for (Parameter parameter : parameters){
System.out.println("获取到参数:" + Name());
夏天夏天
Type type = ParameterizedType();
System.out.Name() + "参数的类型:" + type);
if (type instanceof ParameterizedType){
脚心长水泡
ParameterizedType parameterizedType = (ParameterizedType) type;
System.out.Name() + "参数的原始类型:"+ RawType());
30年战争Type[] types = ActualTypeArguments();
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