spring更好的处理泛型

Posted Bwz_Learning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring更好的处理泛型相关的知识,希望对你有一定的参考价值。

由于泛型擦除,使得Generic无法获取自己的Generic的Type类型。实际上BadClass()实例化以后Class里面就不包括T的信息了,对于Class而言T已经被擦拭为Object,而真正的T参数被转到使用T的方法(或者变量声明或者其它使用T的地方)里面(如果没有那就没有存根),所以无法反射到T的具体类别,也就无法得到T.class。 而getGenericSuperclass()是Generic继承的特例,对于这种情况子类会保存父类的Generic参数类型,返回一个ParameterizedType,这时可以获取到父类的T.class了,这也正是子类确定应该继承什么T的方法

传统Java方式获取泛型信息

继承的父类是泛型(class.getGenericSuperclass())

  • 用到的类

    public class Person<T> 
    
    
    public class Student extends Person<String> 
    
    
  • 测试代码
@Test
public void test01() 
    // 对于继承的父类是泛型的情况
    ParameterizedType genericSuperclass = (ParameterizedType) Student.class.getGenericSuperclass();
    System.out.println(genericSuperclass);
    Type type = genericSuperclass.getActualTypeArguments()[0];
    System.out.println(type);
    System.out.println();
  • 运行结果
com.fanxing.Person<java.lang.String>
class java.lang.String

实现的接口是泛型

  • 用到的类

    public interface IDAO<T> 
    
    
    public class StringDao  implements IDAO<String>
    
    
  • 测试代码
@Test
public void test02() 
    // 对于实现的接口是泛型的处理情况
    ParameterizedType parameterizedType = (ParameterizedType) StringDao.class.getGenericInterfaces()[0];
    System.out.println(parameterizedType);
    Type genericType = parameterizedType.getActualTypeArguments()[0];
    System.out.println(genericType);
    System.out.println();
  • 运行结果
com.fanxing.IDAO<java.lang.String>
class java.lang.String

使用Spring的ResolvableType获取泛型信息

继承的父类是泛型

  • 测试代码
@Test
public void test04() 
    // Spring的提供工具类,用于获取继承的父类是泛型的信息
    ResolvableType resolvableType = ResolvableType.forClass(Student.class);
    System.out.println(resolvableType);
    Class<?> resolve = resolvableType.getSuperType().getGeneric(0).resolve();
    System.out.println(resolve);
  • 运行结果
com.fanxing.Student
class java.lang.String

实现的接口是泛型

  • 测试代码
@Test
public void test03() 
    // Spring的提供工具类,用于获取实现的接口是泛型的信息
    ResolvableType resolvableType = ResolvableType.forClass(StringDao.class);
    System.out.println(resolvableType);
    Class<?> resolve = resolvableType.getInterfaces()[0].getGeneric(0).resolve();
    System.out.println(resolve);
  • 运行结果
com.fanxing.StringDao
class java.lang.String

得到字段级别的泛型信息

用到的Java类
package com.fanxing;

import java.util.List;
import java.util.Map;

public class GenericClass 

    private List<String> listString;
    private List<List<String>> listLists;
    private Map<String, Long> maps;
    private Person<String> persons;

    public GenericClass() 
    

    public List<String> getListString() 
        return listString;
    

    public void setListString(List<String> listString) 
        this.listString = listString;
    

    public Map<String, Long> getMaps() 
        return maps;
    

    public void setMaps(Map<String, Long> maps) 
        this.maps = maps;
    

    public Person<String> getPersons() 
        return persons;
    

    public void setPersons(Person<String> persons) 
        this.persons = persons;
    

    public List<List<String>> getListLists() 
        return listLists;
    

    public void setListLists(List<List<String>> listLists) 
        this.listLists = listLists;
    


自定义的泛型信息
  • 测试代码
// Spring的提供工具类,用于字段的泛型信息,Person<String>
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "persons"));
System.out.println(resolvableType);
// 然后通过如下API得到Person<String>的第0个位置上的泛型实参类型,即String
Class<?> resolve = resolvableType.getGeneric(0).resolve();
System.out.println(resolve);
  • 输出结果
com.fanxing.Person<java.lang.String>
class java.lang.String
获取List属性的泛型
List< String >的情况
  • 测试代码
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "listString"));
System.out.println(resolvableType);
// 然后通过如下API得到Person<String>的第0个位置上的泛型实参类型,即String
Class<?> resolve = resolvableType.getGeneric(0).resolve();
System.out.println(resolve);
  • 运行结果
java.util.List<java.lang.String>
class java.lang.String
List< List < String > > 的情况
  • 测试代码
@Test
public void test07() 
    // Spring的提供工具类,用于字段的泛型信息,List<List<String>>
    ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "listLists"));
    System.out.println(resolvableType);
    // 然后通过如下API得到Person<String>的第0个位置上的泛型实参类型,即String
    // Class<?> resolve =
    // resolvableType.getGeneric(0).getGeneric(0).resolve();
    Class<?> resolve = resolvableType.getGeneric(0, 0).resolve();
    System.out.println(resolve);
    
  • 输出结果
java.util.List<java.util.List<java.lang.String>>
class java.lang.String
获取Map属性的泛型
  • 测试代码
@Test
    public void test08() 
        // Spring的提供工具类,用于字段的泛型信息,List<List<String>>
        ResolvableType resolvableType = ResolvableType//
                .forField(ReflectionUtils.findField(GenericClass.class, "maps"));
        System.out.println(resolvableType);
        // 然后通过如下API得到Person<String>的第0个位置上的泛型实参类型,即String
        Class<?> resolve = resolvableType.getGeneric(0).resolve();
        System.out.println(resolve);
    
  • 运行结果
java.util.Map<java.lang.String, java.lang.Long>
class java.lang.String

得到方法返回值的泛型信息

  • 测试代码
@Test
    public void test09() 
        // Spring的提供工具类,用于方法的返回值的泛型信息,Map<String, Long>
        ResolvableType resolvableType = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenericClass.class, "getMaps"));
        Class<?> resolve = resolvableType.getGeneric(1).resolve();
        System.out.println(resolve);
    
  • 运行结果
@Test
    public void test09() 
        // Spring的提供工具类,用于方法的返回值的泛型信息,Map<String, Long>
        ResolvableType resolvableType = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenericClass.class, "getMaps"));
        Class<?> resolve = resolvableType.getGeneric(1).resolve();
        System.out.println(resolve);
    

参考的博客地址

http://jinnianshilongnian.iteye.com/blog/1993608

以上是关于spring更好的处理泛型的主要内容,如果未能解决你的问题,请参考以下文章

Spring(十三)--Spring泛型处理

来自 WSDL 的 Spring-ws 客户端

在 Spring Boot 中使用 Gradle 从 Swagger OpenAPI 生成 RestClient 存根

Spring Cloud 合约功能

Java-泛型,枚举,注解

Java-泛型,枚举,注解