Spring的API获取泛型实际类型

发布时间:2023年12月24日

学习链接

利用Spring的API获取泛型实际类型

Spring中获取泛型类型

Spring中获取泛型类型

泛型的实际类型获取在写底层基础类的时候,经常会用到,这里将Spring4中关于泛型获取的API归纳整理如下

类上有约束的泛型

BaseService<T> (带泛型父类)

public class BaseService<T> {

}

CustomService<T, K,U> (带泛型接口)

public interface CustomService<T, K, U> {

}

CustomServiceImpl (指定泛型具体类型)

如果是一个很抽象没有加任何限定的泛型,那么是获取不到的。

当然如果是实现了接口或者继承了某个类,那么是可以获取到具体的泛型类型的。

public class CustomServiceImpl
        extends BaseService<List<String>>
        implements CustomService<List<Map<String, Integer>>, 
                                      BaseService<List<Map<String,Integer>>>, 
                                      BaseService>  {



}

GenericTest 获取类上的泛型示例

public class GenericTest {
    public static void main(String[] args) {

        //获取到 CustomServiceImpl 这个类的Type
        ResolvableType oriType = ResolvableType.forClass(CustomServiceImpl.class);

        //获取父类,就是extends的那个类,因为java是单继承,所以只会有一个
        ResolvableType superType = oriType.getSuperType();
        System.out.println(superType.resolve()); // class com.zzhua.service.BaseService
        System.out.println(superType.getGeneric(0).resolve()); // interface java.util.List

        //获取CustomServiceImpl这个类要实现的接口,因为接口可能会有多个,所以是一个数组
        ResolvableType[] interfaces = oriType.getInterfaces();

        for (ResolvableType interfaceResolvableType : interfaces) {
            System.out.println(interfaceResolvableType.resolve()); // interface com.zzhua.service.CustomService
        }

        // 开始进行泛型获取,
        // 接口定义: public interface CustomService<T, K> {}
        // 通过最复杂的:CustomServiceImpl implements CustomService<List<Map<String, Integer>>, BaseService> 举例
        ResolvableType generic1 = interfaces[0].getGeneric(0);
        System.out.println(generic1.toString()); // java.util.List<java.util.Map<java.lang.String, java.lang.Integer>>
        System.out.println(generic1.resolve());  // interface java.util.List

        ResolvableType generic2 = interfaces[0].getGeneric(1); // BaseService
        System.out.println(generic2.toString()); // com.zzhua.service.BaseService<?>
        System.out.println(generic2.resolve());  // class com.zzhua.service.BaseService

        // 第一个0表示获取的是:Map<String, Integer> ,第二个0表示获取的String
        ResolvableType generic0_0 = generic1.getGeneric(0, 0);
        System.out.println(generic0_0.resolve()); // class java.lang.String
        ResolvableType generic0_1 = generic1.getGeneric(0, 1);
        System.out.println(generic0_1.resolve()); // class java.lang.Integer

        // 所以通过以上示例, 可以知道
        // 1. 先去拿具体的类的ResolvableType,
        // 2. 具体的类可以拿到它的 父类的ResolvableType(只会有1个父类), 所有实现接口的ResolvableType(可能会有多个)
        // 3. 继续通过拿到的ResolvableType, 调用它的getGeneric(int... indexes), 里面可传多个参数(表示在泛型中的位置,从0开始)

        // class java.lang.String
        System.out.println(ResolvableType.forClass(CustomServiceImpl.class).getInterfaces()[0].getGeneric(1, 0, 0, 0).resolve());
        // class java.lang.Integer
        System.out.println(ResolvableType.forClass(CustomServiceImpl.class).getInterfaces()[0].getGeneric(1, 0, 0, 1).resolve());

        // class com.zzhua.service.BaseService
        System.out.println(ResolvableType.forClass(CustomServiceImpl.class).getInterfaces()[0].getGeneric(2).resolve());
        // CustomServiceImpl的第三个泛型BaseService没有写明具体的泛型类, 因此这里是null
        System.out.println(ResolvableType.forClass(CustomServiceImpl.class).getInterfaces()[0].getGeneric(2, 0).resolve());




    }
}

获取字段的泛型

public class  GenericInjectTest {

    private Map<String, Map<String, Integer>> map;

  	// ....
    public Map<String, Map<String, Integer>> methodName() {
        return null;
    }
}

如果要获取某个字段的泛型,那么可以采用:

ResolvableType resolvableType4 = ResolvableType.forField(ReflectionUtils.findField(GenricInjectTest.class, "map"));    
resolvableType4.getGeneric(1).getGeneric(1).resolve();
// class java.lang.Integer

获取返回值的泛型参数

ResolvableType resolvableType5 = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenricInjectTest.class, "methodName"));  
System.out.println(resolvableType5.getGeneric(1, 0).resolve()); 
// class java.lang.String
文章来源:https://blog.csdn.net/qq_16992475/article/details/135178707
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。