zoukankan      html  css  js  c++  java
  • 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;
            }
        }
    }
  • 相关阅读:
    BOM
    no response from Graphic Screen Painter Exiting
    Windows Mobile 中模拟按键
    C# 获取汉字拼音首字母
    Web Service介绍
    .net/c#中栈和堆的区别及代码在栈和堆中的执行流程详解
    使用JSON加速AJAX(By Sean Kelly)
    Sql字符串操作函数
    一个简单AJAX注册示例
    .Net平台开发的技术规范与实践精华总结
  • 原文地址:https://www.cnblogs.com/wly1-6/p/10303041.html
Copyright © 2011-2022 走看看