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

简介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(泛型数组)解析。

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;
        }
    }
}
原文地址:https://www.cnblogs.com/wly1-6/p/10303041.html