ResolvableType是Spring4提供的新的特性。它封装了Java类型,提供对父类,接口和通用参数的访问,提供最终解析为类的能力。
在jdk中,Type接口代表一种类型,所有的具体类型都需要实现这个接口。
从上图可以看出,Java语法中的类型可以分为5大类:
- 组件类型为参数化类型或类型变量的数组
- 参数化类型
- 通配符表达式类型
- 类型变量
- 所有定义的Class(每个类都是一个具体的类型)
除Class类以外的4个接口是jdk1.5以后出现的,因为单纯的Class类无法描述泛型信息
可以通过一段程序来直观看一下这5大类到底是什么:
1 | public class TypeDemo<T> { |
输出结果为:
1 | type of a: class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl |
随着泛型的使用越来越多,获取泛型实际类型信息的需求也会出现,如果使用原生API,需要很多步才能获取到泛型。比如:
1 | ParameterizedType parameterizedType = (ParameterizedType) ABService.class.getGenericInterfaces()[0]; |
Spring提供的ResolvableType API,提供了更加简单易用的泛型操作支持:
1 | ResolvableType resolvableType = ResolvableType.forClass(ABService.class); |
ResolvableType详解
类型的泛型信息
假设我们的类定义如下:
1 | public interface Service<N, M> { |
如下得到类的ResolvableType,然后得到泛型参数第一个位置的类型信息:
1 | ResolvableType resolvableType = ResolvableType.forClass(ABService.class); |
通过getGeneric()
(泛型参数索引)得到某个位置的泛型,resolve()
把实际泛型参数解析出来
字段级别的泛型信息
假设我们的测试类如下:
1 | public class GenericInjectTest { |
如下得到字段级别的ResolvableType:
1 | resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericInjectTest.class, "cdService")); |
比如List<List<String>> list
是一种嵌套的泛型用例,我们可以通过如下操作获取嵌套的String类型:
1 | resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericInjectTest.class, "list")); |
比如Map<String, Map<String, Integer>> map
我们想得到Integer,可以使用:
1 | resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericInjectTest.class, "map")); |
方法返回值的泛型信息
得到method方法的返回值HashMap<String, List<String>> method()
,然后获得Map中List中的String泛型实参:
1 | resolvableType = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenericInjectTest.class, "method")); |
构造器参数的泛型信息
如下可以获得构造器第1个参数(Map<String, Map<String, Integer>>
)中的Integer:
1 | resolvableType = ResolvableType.forConstructorParameter(ClassUtils.getConstructorIfAvailable(GenericInjectTest.class, List.class, Map.class), 1); |
数组组件类型的泛型信息
对于List<String>[] array
,如下获取List的泛型实参String:
1 | resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericInjectTest.class, "array")); |
自定义泛型类型
1 | // 相当于创建一个List<String>类型 |
泛型等价比较
如下创建一个List<Integer>[]
数组和一个List<String>[]
数组比较,将返回false
1 | ResolvableType resolvableType1 = ResolvableType.forClassWithGenerics(List.class, Integer.class); |
Spring中的泛型注入
// TODO
https://my.oschina.net/lixin91/blog/677109
http://jinnianshilongnian.iteye.com/blog/1993608
http://blog.csdn.net/zbw18297786698/article/details/73441623
https://clarkdo.js.org/java/spring/2014/07/03/9/