通过反射获得泛型实际类型
1.获得类的泛型
子类继承泛型父类,并对泛型进行指定,通过反射获得指定类型,
1.使用getGenericSuperclass()方法获得泛型父类
2.判断是不是参数化类型是的话强转类型为ParameterizedType
3.使用ParameterizedType的方法getActualTypeArguments()获得泛型实际类型
代码如下
public class Demo1<T> {
public void study(Map<String, Integer> map, T t,String str){
}
/*
* 继承泛型父类并指定String类型
* */
public class Demo2 extends Demo1<String>{
}
public static void main(String[] args) {
Demo1.Demo2 demo = new Demo1<>().new Demo2();
//获得带有泛型的父类
Type genericSuperclass = demo.getClass().getGenericSuperclass();
//判断父类是不是参数化的类型,如果是强转成ParameterizedType
if (genericSuperclass instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType)genericSuperclass;
//获得Demo1<String>,<>中的实际类型参数
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
//获得参数类型
Class<?> clazz = (Class<?>)actualTypeArguments[0];
System.out.println(clazz);
}
}
}
结果:
2.获得方法参数中的泛型实际类型
方法参数使用了带有泛型的类如Map<K,V>,获得泛型的实际类型,代码如下:
1.反射获得对应方法
2.调用getGenericParameterTypes()方法获得方法参数类型集合
3.遍历集合对ParameterizedType类型参数进行操作
4.使用ParameterizedType的方法getActualTypeArguments()获得泛型实际类型
public class Demo {
//一个方法有Map类型和List类型的参数,并指定泛型
public void study(Map<String, Integer> map, List<String> list){
}
public static void main(String[] args) {
try {
//通过反射获得该方法
Method study = Demo.class.getMethod("study", Map.class, List.class);
//获得该方法的所有参数类型
Type[] genericParameterTypes = study.getGenericParameterTypes();
for (Type type : genericParameterTypes){
System.out.println("##"+ type);
//如果参数为参数化的类型进行强转
if (type instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType)type;
//获得参数化类型中实际参数(Map<String, Integer> 中<>内定义的参数)
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
//遍历输出
for (Type tt : actualTypeArguments){
System.out.println(tt);
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
运行结果
3.获得方法返回值中的泛型实际类型
使用getGenericReturnType()方法获得方法返回值类型,之后的操作和获得参数返回类型方法类似
public class Demo2 {
//一个方法的返回类型是Map并指定了泛型类型
public Map<String, Integer> study(){
return new HashMap<String,Integer>();
}
public static void main(String[] args) {
try {
//通过反射获得该方法
Method study = Demo2.class.getMethod("study");
//获得方法的返回类型
Type genericReturnType = study.getGenericReturnType();
System.out.println("###" + genericReturnType);
////如果返回值类型为参数化的类型进行强转
if (genericReturnType instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType)genericReturnType;
//获得参数化类型中实际参数(Map<String, Integer> 中<>内定义的参数)
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
//遍历输出
for (Type type : actualTypeArguments){
System.out.println(type);
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
运行结果
4.获得通配符类型的上下界
先按照获得参数泛型实际类型的方法获得通配符表达式(? extends T 或?super T),再进行后续操作。
使用WildcardType接口的getUpperBounds()和getLowerBounds()来获得类型的上下界
public class Demo3 {
//study方法传入List类似参数,其中List指定类型上界为Demo3
public void study(List<? extends Demo3> list){
}
public static void main(String[] args) {
try {
Method study = Demo3.class.getMethod("study", List.class);
Type[] genericParameterTypes = study.getGenericParameterTypes();
//获得List参数(java.util.List<? extends com.fxl.GenenricReflect.Demo3>)
Type type = genericParameterTypes[0];
if (type instanceof ParameterizedType){
System.out.println(type);
//获得List参数中的泛型实际类型(? extends com.fxl.GenenricReflect.Demo3)
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type mytypes : actualTypeArguments){
//判断是不是WildcardType并强转
if (mytypes instanceof WildcardType){
WildcardType wt = (WildcardType)mytypes;
//获得类型的上界(class com.fxl.GenenricReflect.Demo3)
Type[] upperBounds = wt.getUpperBounds();
System.out.println(upperBounds[0]);
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
运行结果
个人笔记,如有错误还望指出