Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)

时间:2022-01-07 01:46:31

简介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工具类:

Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)

如上图:

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

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

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

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

public class TypeParameterResolver {

    /**
* srcType:被反射时调用的类型,即被解析的方法或字段是通过那个类型反射出来的
*
* declaringClass:定义被解析的方法或字段的class类型,即这个方法/字段是定义在那个class中的
*
* example:
*
* <p>
* public interface A<N>{
* public N getVal();
* }
*
* public interface B extends A<String>{}
* </p>
* 如上面代码所示,如果通过B接口获取到的getVal方法并对其返回值进行解析,则srcType表示B的类型,declaringClass表示A的类型
*/
public static Type resolveFieldType(Field field, Type srcType) {
// 获取字段的声明类型
Type fieldType = field.getGenericType(); // 获取字段定义所在的类的Class对象
Class<?> declaringClass = field.getDeclaringClass(); // 调用 resolveType方法进行后续处理
return resolveType(fieldType, srcType, declaringClass);
} public static Type resolveReturnType(Method method, Type srcType) {
//获取方法的返回类型
Type returnType = method.getGenericReturnType(); //获取方法定义的类的类型
Class<?> declaringClass = method.getDeclaringClass(); // 调用 resolveType方法进行后续处理
return resolveType(returnType, srcType, declaringClass);
} public static Type[] resolveParamTypes(Method method, Type srcType) {
//获取方法所有参数类型
Type[] paramTypes = method.getGenericParameterTypes(); //获取方法定义的类类型
Class<?> declaringClass = method.getDeclaringClass(); Type[] result = new Type[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
// 调用 resolveType方法进行后续处理
result[i] = resolveType(paramTypes[i], srcType, declaringClass);
}
return result;
} private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) {
if (type instanceof TypeVariable) {
//解析TypeVariable类型
return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass);
} else if (type instanceof ParameterizedType) {
//解析ParameterizedType类型
return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass);
} else if (type instanceof GenericArrayType) {
//解析GenericArrayType类型
return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass);
} else {
//如果为普通的Class类型就直接返回
return type;
}
} private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type srcType, Class<?> declaringClass) {
//去掉一层[]后的泛型类型变量
Type componentType = genericArrayType.getGenericComponentType();
Type resolvedComponentType = null; //根据去掉一维数组后的类型变量,再根据其类型递归解析
if (componentType instanceof TypeVariable) { //如果去掉后为TypeVariable类型,则调用resolveTypeVar方法
resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, srcType, declaringClass);
} else if (componentType instanceof GenericArrayType) { //如果去掉仍为GenericArrayType类型,则递归调用resolveGenericArrayType方法
resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, srcType, declaringClass);
} else if (componentType instanceof ParameterizedType) { //如果去掉后为ParameterizedType类型,则调用resolveParameterizedType方法处理
resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, srcType, declaringClass);
}
if (resolvedComponentType instanceof Class) { //如果处理后的结果为基本的Class类型,则返回对应的Class的数组类型(处理N[][])。
return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass();
} else { //否则包装为自定义的GenericArrayTypeImpl类型
return new GenericArrayTypeImpl(resolvedComponentType);
}
} private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) {
//获取泛型的基本类型
Class<?> rawType = (Class<?>) parameterizedType.getRawType(); //获取泛型中的类型实参
Type[] typeArgs = parameterizedType.getActualTypeArguments(); //递归处理其类型实参
Type[] args = new Type[typeArgs.length]; //判断对应参数的类型,分别进行递归处理
for (int i = 0; i < typeArgs.length; i++) {
if (typeArgs[i] instanceof TypeVariable) {
//解析TypeVariable类型
args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass);
} else if (typeArgs[i] instanceof ParameterizedType) {
//解析ParameterizedType类型
args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass);
} else if (typeArgs[i] instanceof WildcardType) {
//是解析WildcardType类型(其类型实参是通配符表达式)
args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass);
} else {
//普通Class类型,直接返回
args[i] = typeArgs[i];
}
} //返回自定以类型
return new ParameterizedTypeImpl(rawType, null, args);
} /**
* 在对通配符进行解析时,主要对其上下限的类型进行解析
*/
private static Type resolveWildcardType(WildcardType wildcardType, Type srcType, Class<?> declaringClass) {
//获取下限
Type[] lowerBounds = resolveWildcardTypeBounds(wildcardType.getLowerBounds(), srcType, declaringClass); //获取上限
Type[] upperBounds = resolveWildcardTypeBounds(wildcardType.getUpperBounds(), srcType, declaringClass); //包装成自定义的WildcardTypeImpl类型返回
return new WildcardTypeImpl(lowerBounds, upperBounds);
} private static Type[] resolveWildcardTypeBounds(Type[] bounds, Type srcType, Class<?> declaringClass) {
Type[] result = new Type[bounds.length];
for (int i = 0; i < bounds.length; i++) {
//根据上下限不同的类型,进行解析
if (bounds[i] instanceof TypeVariable) {
result[i] = resolveTypeVar((TypeVariable<?>) bounds[i], srcType, declaringClass);
} else if (bounds[i] instanceof ParameterizedType) {
result[i] = resolveParameterizedType((ParameterizedType) bounds[i], srcType, declaringClass);
} else if (bounds[i] instanceof WildcardType) {
result[i] = resolveWildcardType((WildcardType) bounds[i], srcType, declaringClass);
} else {
result[i] = bounds[i];
}
}
return result;
} /**
* 解析具体的类型变量指代的类型。
* 1.如果srcType的Class类型和declaringClass为同一个类,表示获取该类型变量时被反射的类型就是其定义的类型,
* 则取该类型变量定义是有没有上限,如果有则使用其上限代表其类型,否则就用Object。
*
* 2.如果不是,则代表declaringClass是srcType的父类或者实现的接口,则解析继承中有没有定义其代表的类型
*/
private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {
Type result = null;
Class<?> clazz = null;
/**
* 判断srcType是否为Class/ParameterizedType类型
* 如果不是这两种类型这抛出异常
*/
if (srcType instanceof Class) {
clazz = (Class<?>) srcType;
} else if (srcType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) srcType;
clazz = (Class<?>) parameterizedType.getRawType();
} else {
throw new IllegalArgumentException("The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass());
} /**
* 如果declaringClass和srcType的实际类型相等则表示无法获取其类型实参。
* 如果typeVar有上限限定则返回其上限,否则返回Object处理
*/
if (clazz == declaringClass) {
Type[] bounds = typeVar.getBounds();
if (bounds.length > 0) {
return bounds[0];
}
return Object.class;
} Type superclass = clazz.getGenericSuperclass();
result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass);
if (result != null) {
return result;
} /**
* 如果父类的定义中没有,则处理其实现的接口。
*/
Type[] superInterfaces = clazz.getGenericInterfaces();
for (Type superInterface : superInterfaces) {
result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface);
if (result != null) {
return result;
}
}
//如果父类或者实现的接口中都没有获取到形参对应的实参,则返回Object.class
return Object.class;
} /**
* 通过对父类/接口的扫描获取其typeVar指代的实际类型
*/
private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) {
Type result = null;
/**
* 判断处理的父类superclass是否为参数化类型,如果不是则代表declaringClass和superclass的基本Class
* 类型不是同一个类。
*/
if (superclass instanceof ParameterizedType) {
//如果为ParameterizedType,则获取它基本类型
ParameterizedType parentAsType = (ParameterizedType) superclass;
Class<?> parentAsClass = (Class<?>) parentAsType.getRawType(); if (declaringClass == parentAsClass) {
//如果declaringClass和parentAsClass表示同一类型,则通过typeVar在declaringClass的泛型形参的index获取其在supperClass中定义的类型实参
Type[] typeArgs = parentAsType.getActualTypeArguments();
TypeVariable<?>[] declaredTypeVars = declaringClass.getTypeParameters(); for (int i = 0; i < declaredTypeVars.length; i++) {
//循环判断当前处理的类型是否属于所属的类型描述符中的变量
if (declaredTypeVars[i] == typeVar) {
/**
* 如果supperClass中定义的类型形参还是类型变量则取srcType中的类型形参的定义
* 如果srcType中的类型形参还是类型变量则不处理。
*/
if (typeArgs[i] instanceof TypeVariable) {
//其子类中的所有泛型描述符
TypeVariable<?>[] typeParams = clazz.getTypeParameters();
for (int j = 0; j < typeParams.length; j++) {
if (typeParams[j] == typeArgs[i]) {
//判断是否为ParameterizedType,则去实际代表的类型
if (srcType instanceof ParameterizedType) {
result = ((ParameterizedType) srcType).getActualTypeArguments()[j];
}
break;
}
}
} else {
//如果不是TypeVariable,直接取对应的类型
result = typeArgs[i];
}
}
}
} else if (declaringClass.isAssignableFrom(parentAsClass)) {
//通过判断superclass是否是declaringClass的子类(由于java类可以实现多个接口),进行递归解析
result = resolveTypeVar(typeVar, parentAsType, declaringClass);
}
} else if (superclass instanceof Class) {
//如果superclass为Class类型,通过判断superclass是否是declaringClass的子类(由于java类可以实现多个接口),进行递归解析
if (declaringClass.isAssignableFrom((Class<?>) superclass)) {
result = resolveTypeVar(typeVar, superclass, declaringClass);
}
}
return result;
} private TypeParameterResolver() {
super();
} static class ParameterizedTypeImpl implements ParameterizedType {
private Class<?> rawType; private Type ownerType; private Type[] actualTypeArguments; public ParameterizedTypeImpl(Class<?> rawType, Type ownerType, Type[] actualTypeArguments) {
super();
this.rawType = rawType;
this.ownerType = ownerType;
this.actualTypeArguments = actualTypeArguments;
} @Override
public Type[] getActualTypeArguments() {
return actualTypeArguments;
} @Override
public Type getOwnerType() {
return ownerType;
} @Override
public Type getRawType() {
return rawType;
} @Override
public String toString() {
return "ParameterizedTypeImpl [rawType=" + rawType + ", ownerType=" + ownerType + ", actualTypeArguments=" + Arrays.toString(actualTypeArguments) + "]";
}
} static class WildcardTypeImpl implements WildcardType {
private Type[] lowerBounds; private Type[] upperBounds; private WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) {
super();
this.lowerBounds = lowerBounds;
this.upperBounds = upperBounds;
} @Override
public Type[] getLowerBounds() {
return lowerBounds;
} @Override
public Type[] getUpperBounds() {
return upperBounds;
}
} static class GenericArrayTypeImpl implements GenericArrayType {
private Type genericComponentType; private GenericArrayTypeImpl(Type genericComponentType) {
super();
this.genericComponentType = genericComponentType;
} @Override
public Type getGenericComponentType() {
return genericComponentType;
}
}
}