泛型实际类型获取

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

类上有约束的泛型

请注意我的措辞,如果是一个很抽象没有加任何限定的泛型,那么是获取不到的。
当然如果是实现了接口或者继承了某个类,那么是可以获取到具体的泛型类型的。

  1. /**
  2. * 泛型类
  3. */
  4. public class CustomServiceImpl extends BaseService<List<String>>
  5. implements CustomService<List<Map<String, Integer>>, BaseService>
  6. {
  7. //......
  8. }
  9. @Test
  10. public void testGeneric() {
  11. //获取到 CustomServiceImpl 这个类的Type
  12. ResolvableType oriType = ResolvableType.forClass(CustomServiceImpl.class);
  13. //获取CustomServiceImpl这个类要实现的接口,因为接口可能会有多个,所以是一个数组
  14. ResolvableType[] interfaces = oriType.getInterfaces();
  15. //获取父类,就是extends的那个类,因为java是单继承,所以只会有一个
  16. ResolvableType superType = oriType.getSuperType();
  17. //开始进行泛型获取,通过最复杂的:CustomService<List<Map<String, Integer>>, BaseService> 举例
  18. ResolvableType generic1 = interfaces[0].getGeneric(0); //List<Map<String, Integer>>
  19. ResolvableType generic2 = interfaces[0].getGeneric(1); //BaseService
  20. //第一个0表示获取的是:Map<String, Integer> ,第二个0表示获取的String
  21. ResolvableType generic1_0 = generic1.getGeneric(0, 0);
  22. ResolvableType generic1_1 = generic1.getGeneric(0, 1); //Integer
  23. //获取到实际的Class
  24. Class<?> resolve = generic1_1.resolve();
  25. System.out.println(resolve);
  26. }

获取字段的泛型

  1. public class GenricInjectTest {
  2. private Map<String, Map<String, Integer>> map;
  3. // ....
  4. }

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

  1. ResolvableType resolvableType4 = ResolvableType.forField(ReflectionUtils.findField(GenricInjectTest.class, "map"));
  2. resolvableType4.getGeneric(1).getGeneric(1).resolve();
  3. //结果是Integer

获取返回值的泛型参数

  1. ResolvableType resolvableType5 = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenricInjectTest.class, "methodName"));
  2. System.out.println(resolvableType5.getGeneric(1, 0).resolve());