经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)
来源:cnblogs  作者:^^ITBOY^^  时间:2019/1/23 9:11:52  对本文有异议

简介TypeParameterResolver是一个工具类,提供一系列的静态方法,去解析类中的字段、方法返回值、方法参数的类型。

在正式介绍TypeParameterResolver之前,先介绍一个JDK提供的接口Type,因为TypeParameterResolver的实现会涉及到它的实现;它是所有类型的父接口,在JDK实现中,Type接口拥有四个接口和一个实现类分别代表不同的数据类型;

分别是:

  • 类Class:表示原始类型。Class对象表示JVM的一个类和接口,每个java类在JVM里都是一个Class对象,在程序中可以通过"类名.class","对象.getClass","Class.forName()"获取到,数组也被映射为Class对象,所有元素类型相同且维数相同的数组共享同一个Class对象;
  • 接口ParameterizedType:表示的是参数化类型,例如:List<String>、Map<Integer,String>这种带范型的类型;
  • 接口TypeVariable:表示的类型变量,用来反映在JVM编译泛型前的信息,例如:List<T>中的T就是类型变量,在编译时需被转换成一个具体的类型后才能被使用。
  • 接口GenericArrayType:表示的是数组类型且组成元素是ParameterizedType或TypeVariable。例如:List<String>[]或T[]
  • 接口WildcardType:表示的是通配符类型,;例如 ? extends Number 和 ? super Integer 。

Type的实现和子接口源码就不贴出来了,下面会介绍一下上述四个接口的主要方法

  • 接口ParameterizedType:
    • Type  getRawType( )——返回参数化类型的最外层类型,例如List<String> => List;
    • Type[ ]  getActualTypeArguments( )——获取参数化类型的类型变量或者实际类型列表,例如Map<Integer,String>的实际类型列表Integer和String。需要注意的是该列表的元素也是Type接口,可能存在多层嵌套的情况;
    • Type  getOwnerType( )——返回的是类型所属的类型,例如存在A<T>类,其中定义了内部类InnerA<I>,则InnerA<I>的所属类型为A<T>,如果是顶层类型,则返回null;
  • 接口TypeVariable:
    • Type[ ]  getBounds( )——获取类型变量的上边界,如未明确声明上边界则默认为Object,例如:class Test<K extends Person>中K的上边界就是Person;
    • D  getGenericDecralation( )——获取声明该类型变量的原始类型,例如class Test<K extends Person>中的原始类型就是Test;
    • String  getName( )——获取在源码中定义是的名字,上例为K;
  • 接口GenericArrayType:Type  getGenericComponentType( )——返回数组的元素类型
  • 接口WildcardType:
    • Type[ ]  getUpperBounds( )——返回泛型变量的上界;
    • Type[ ]  getLowerBounds( )——返回泛型变量的下界;
       

下面正式介绍本篇主角TypeParameterResolver工具类:

如上图:

工具类主要有三个对外开放的方法,分别是

resolveFieldType(解析字段的类型),resolveReturnType(解析方法返回类型)和resolveParamTypes(解析方法入参的类型)。

三个方法获取到需要解析的类型后,调用resolveType方法进行统一的处理。

resolveType方法根据入参的类型的类别,分别调用resolveTypeVar(类型变量解析),resolveParameterizedType(参数化类型解析)和resolveGenericArrayType(泛型数组)解析。

  1. public class TypeParameterResolver {
  2. /**
  3. * srcType:被反射时调用的类型,即被解析的方法或字段是通过那个类型反射出来的
  4. *
  5. * declaringClass:定义被解析的方法或字段的class类型,即这个方法/字段是定义在那个class中的
  6. *
  7. * example:
  8. *
  9. * <p>
  10. * public interface A<N>{
  11. * public N getVal();
  12. * }
  13. *
  14. * public interface B extends A<String>{}
  15. * </p>
  16. * 如上面代码所示,如果通过B接口获取到的getVal方法并对其返回值进行解析,则srcType表示B的类型,declaringClass表示A的类型
  17. */
  18. public static Type resolveFieldType(Field field, Type srcType) {
  19. // 获取字段的声明类型
  20. Type fieldType = field.getGenericType();
  21. // 获取字段定义所在的类的Class对象
  22. Class<?> declaringClass = field.getDeclaringClass();
  23. // 调用 resolveType方法进行后续处理
  24. return resolveType(fieldType, srcType, declaringClass);
  25. }
  26. public static Type resolveReturnType(Method method, Type srcType) {
  27. //获取方法的返回类型
  28. Type returnType = method.getGenericReturnType();
  29. //获取方法定义的类的类型
  30. Class<?> declaringClass = method.getDeclaringClass();
  31. // 调用 resolveType方法进行后续处理
  32. return resolveType(returnType, srcType, declaringClass);
  33. }
  34. public static Type[] resolveParamTypes(Method method, Type srcType) {
  35. //获取方法所有参数类型
  36. Type[] paramTypes = method.getGenericParameterTypes();
  37. //获取方法定义的类类型
  38. Class<?> declaringClass = method.getDeclaringClass();
  39. Type[] result = new Type[paramTypes.length];
  40. for (int i = 0; i < paramTypes.length; i++) {
  41. // 调用 resolveType方法进行后续处理
  42. result[i] = resolveType(paramTypes[i], srcType, declaringClass);
  43. }
  44. return result;
  45. }
  46. private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) {
  47. if (type instanceof TypeVariable) {
  48. //解析TypeVariable类型
  49. return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass);
  50. } else if (type instanceof ParameterizedType) {
  51. //解析ParameterizedType类型
  52. return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass);
  53. } else if (type instanceof GenericArrayType) {
  54. //解析GenericArrayType类型
  55. return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass);
  56. } else {
  57. //如果为普通的Class类型就直接返回
  58. return type;
  59. }
  60. }
  61. private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type srcType, Class<?> declaringClass) {
  62. //去掉一层[]后的泛型类型变量
  63. Type componentType = genericArrayType.getGenericComponentType();
  64. Type resolvedComponentType = null;
  65. //根据去掉一维数组后的类型变量,再根据其类型递归解析
  66. if (componentType instanceof TypeVariable) {
  67. //如果去掉后为TypeVariable类型,则调用resolveTypeVar方法
  68. resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, srcType, declaringClass);
  69. } else if (componentType instanceof GenericArrayType) {
  70. //如果去掉仍为GenericArrayType类型,则递归调用resolveGenericArrayType方法
  71. resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, srcType, declaringClass);
  72. } else if (componentType instanceof ParameterizedType) {
  73. //如果去掉后为ParameterizedType类型,则调用resolveParameterizedType方法处理
  74. resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, srcType, declaringClass);
  75. }
  76. if (resolvedComponentType instanceof Class) {
  77. //如果处理后的结果为基本的Class类型,则返回对应的Class的数组类型(处理N[][])。
  78. return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass();
  79. } else {
  80. //否则包装为自定义的GenericArrayTypeImpl类型
  81. return new GenericArrayTypeImpl(resolvedComponentType);
  82. }
  83. }
  84. private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) {
  85. //获取泛型的基本类型
  86. Class<?> rawType = (Class<?>) parameterizedType.getRawType();
  87. //获取泛型中的类型实参
  88. Type[] typeArgs = parameterizedType.getActualTypeArguments();
  89. //递归处理其类型实参
  90. Type[] args = new Type[typeArgs.length];
  91. //判断对应参数的类型,分别进行递归处理
  92. for (int i = 0; i < typeArgs.length; i++) {
  93. if (typeArgs[i] instanceof TypeVariable) {
  94. //解析TypeVariable类型
  95. args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass);
  96. } else if (typeArgs[i] instanceof ParameterizedType) {
  97. //解析ParameterizedType类型
  98. args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass);
  99. } else if (typeArgs[i] instanceof WildcardType) {
  100. //是解析WildcardType类型(其类型实参是通配符表达式)
  101. args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass);
  102. } else {
  103. //普通Class类型,直接返回
  104. args[i] = typeArgs[i];
  105. }
  106. }
  107. //返回自定以类型
  108. return new ParameterizedTypeImpl(rawType, null, args);
  109. }
  110. /**
  111. * 在对通配符进行解析时,主要对其上下限的类型进行解析
  112. */
  113. private static Type resolveWildcardType(WildcardType wildcardType, Type srcType, Class<?> declaringClass) {
  114. //获取下限
  115. Type[] lowerBounds = resolveWildcardTypeBounds(wildcardType.getLowerBounds(), srcType, declaringClass);
  116. //获取上限
  117. Type[] upperBounds = resolveWildcardTypeBounds(wildcardType.getUpperBounds(), srcType, declaringClass);
  118. //包装成自定义的WildcardTypeImpl类型返回
  119. return new WildcardTypeImpl(lowerBounds, upperBounds);
  120. }
  121. private static Type[] resolveWildcardTypeBounds(Type[] bounds, Type srcType, Class<?> declaringClass) {
  122. Type[] result = new Type[bounds.length];
  123. for (int i = 0; i < bounds.length; i++) {
  124. //根据上下限不同的类型,进行解析
  125. if (bounds[i] instanceof TypeVariable) {
  126. result[i] = resolveTypeVar((TypeVariable<?>) bounds[i], srcType, declaringClass);
  127. } else if (bounds[i] instanceof ParameterizedType) {
  128. result[i] = resolveParameterizedType((ParameterizedType) bounds[i], srcType, declaringClass);
  129. } else if (bounds[i] instanceof WildcardType) {
  130. result[i] = resolveWildcardType((WildcardType) bounds[i], srcType, declaringClass);
  131. } else {
  132. result[i] = bounds[i];
  133. }
  134. }
  135. return result;
  136. }
  137. /**
  138. * 解析具体的类型变量指代的类型。
  139. * 1.如果srcType的Class类型和declaringClass为同一个类,表示获取该类型变量时被反射的类型就是其定义的类型,
  140. * 则取该类型变量定义是有没有上限,如果有则使用其上限代表其类型,否则就用Object。
  141. *
  142. * 2.如果不是,则代表declaringClass是srcType的父类或者实现的接口,则解析继承中有没有定义其代表的类型
  143. */
  144. private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {
  145. Type result = null;
  146. Class<?> clazz = null;
  147. /**
  148. * 判断srcType是否为Class/ParameterizedType类型
  149. * 如果不是这两种类型这抛出异常
  150. */
  151. if (srcType instanceof Class) {
  152. clazz = (Class<?>) srcType;
  153. } else if (srcType instanceof ParameterizedType) {
  154. ParameterizedType parameterizedType = (ParameterizedType) srcType;
  155. clazz = (Class<?>) parameterizedType.getRawType();
  156. } else {
  157. throw new IllegalArgumentException("The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass());
  158. }
  159. /**
  160. * 如果declaringClass和srcType的实际类型相等则表示无法获取其类型实参。
  161. * 如果typeVar有上限限定则返回其上限,否则返回Object处理
  162. */
  163. if (clazz == declaringClass) {
  164. Type[] bounds = typeVar.getBounds();
  165. if (bounds.length > 0) {
  166. return bounds[0];
  167. }
  168. return Object.class;
  169. }
  170. Type superclass = clazz.getGenericSuperclass();
  171. result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass);
  172. if (result != null) {
  173. return result;
  174. }
  175. /**
  176. * 如果父类的定义中没有,则处理其实现的接口。
  177. */
  178. Type[] superInterfaces = clazz.getGenericInterfaces();
  179. for (Type superInterface : superInterfaces) {
  180. result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface);
  181. if (result != null) {
  182. return result;
  183. }
  184. }
  185. //如果父类或者实现的接口中都没有获取到形参对应的实参,则返回Object.class
  186. return Object.class;
  187. }
  188. /**
  189. * 通过对父类/接口的扫描获取其typeVar指代的实际类型
  190. */
  191. private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) {
  192. Type result = null;
  193. /**
  194. * 判断处理的父类superclass是否为参数化类型,如果不是则代表declaringClass和superclass的基本Class
  195. * 类型不是同一个类。
  196. */
  197. if (superclass instanceof ParameterizedType) {
  198. //如果为ParameterizedType,则获取它基本类型
  199. ParameterizedType parentAsType = (ParameterizedType) superclass;
  200. Class<?> parentAsClass = (Class<?>) parentAsType.getRawType();
  201. if (declaringClass == parentAsClass) {
  202. //如果declaringClass和parentAsClass表示同一类型,则通过typeVar在declaringClass的泛型形参的index获取其在supperClass中定义的类型实参
  203. Type[] typeArgs = parentAsType.getActualTypeArguments();
  204. TypeVariable<?>[] declaredTypeVars = declaringClass.getTypeParameters();
  205. for (int i = 0; i < declaredTypeVars.length; i++) {
  206. //循环判断当前处理的类型是否属于所属的类型描述符中的变量
  207. if (declaredTypeVars[i] == typeVar) {
  208. /**
  209. * 如果supperClass中定义的类型形参还是类型变量则取srcType中的类型形参的定义
  210. * 如果srcType中的类型形参还是类型变量则不处理。
  211. */
  212. if (typeArgs[i] instanceof TypeVariable) {
  213. //其子类中的所有泛型描述符
  214. TypeVariable<?>[] typeParams = clazz.getTypeParameters();
  215. for (int j = 0; j < typeParams.length; j++) {
  216. if (typeParams[j] == typeArgs[i]) {
  217. //判断是否为ParameterizedType,则去实际代表的类型
  218. if (srcType instanceof ParameterizedType) {
  219. result = ((ParameterizedType) srcType).getActualTypeArguments()[j];
  220. }
  221. break;
  222. }
  223. }
  224. } else {
  225. //如果不是TypeVariable,直接取对应的类型
  226. result = typeArgs[i];
  227. }
  228. }
  229. }
  230. } else if (declaringClass.isAssignableFrom(parentAsClass)) {
  231. //通过判断superclass是否是declaringClass的子类(由于java类可以实现多个接口),进行递归解析
  232. result = resolveTypeVar(typeVar, parentAsType, declaringClass);
  233. }
  234. } else if (superclass instanceof Class) {
  235. //如果superclass为Class类型,通过判断superclass是否是declaringClass的子类(由于java类可以实现多个接口),进行递归解析
  236. if (declaringClass.isAssignableFrom((Class<?>) superclass)) {
  237. result = resolveTypeVar(typeVar, superclass, declaringClass);
  238. }
  239. }
  240. return result;
  241. }
  242. private TypeParameterResolver() {
  243. super();
  244. }
  245. static class ParameterizedTypeImpl implements ParameterizedType {
  246. private Class<?> rawType;
  247. private Type ownerType;
  248. private Type[] actualTypeArguments;
  249. public ParameterizedTypeImpl(Class<?> rawType, Type ownerType, Type[] actualTypeArguments) {
  250. super();
  251. this.rawType = rawType;
  252. this.ownerType = ownerType;
  253. this.actualTypeArguments = actualTypeArguments;
  254. }
  255. @Override
  256. public Type[] getActualTypeArguments() {
  257. return actualTypeArguments;
  258. }
  259. @Override
  260. public Type getOwnerType() {
  261. return ownerType;
  262. }
  263. @Override
  264. public Type getRawType() {
  265. return rawType;
  266. }
  267. @Override
  268. public String toString() {
  269. return "ParameterizedTypeImpl [rawType=" + rawType + ", ownerType=" + ownerType + ", actualTypeArguments=" + Arrays.toString(actualTypeArguments) + "]";
  270. }
  271. }
  272. static class WildcardTypeImpl implements WildcardType {
  273. private Type[] lowerBounds;
  274. private Type[] upperBounds;
  275. private WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) {
  276. super();
  277. this.lowerBounds = lowerBounds;
  278. this.upperBounds = upperBounds;
  279. }
  280. @Override
  281. public Type[] getLowerBounds() {
  282. return lowerBounds;
  283. }
  284. @Override
  285. public Type[] getUpperBounds() {
  286. return upperBounds;
  287. }
  288. }
  289. static class GenericArrayTypeImpl implements GenericArrayType {
  290. private Type genericComponentType;
  291. private GenericArrayTypeImpl(Type genericComponentType) {
  292. super();
  293. this.genericComponentType = genericComponentType;
  294. }
  295. @Override
  296. public Type getGenericComponentType() {
  297. return genericComponentType;
  298. }
  299. }
  300. }

 

原文链接:http://www.cnblogs.com/wly1-6/p/10303041.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号