通过反射获得泛型实际类型

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();
        }
    }
}

运行结果
在这里插入图片描述
个人笔记,如有错误还望指出

猜你喜欢

转载自blog.csdn.net/fxl5202301/article/details/85291493