关于 Type 和 ResolvableType

前言

Type: java.lang.reflect.Typejava 中对所有 类型 的顶层抽象,所谓类型,即 Class、泛型数组、参数类型、参数类型

ResolvableType: org.springframework.core.ResolvableTypeSpringType 的封装,提供对 Type 的访问方法

版本

JDK11
Spring 5.2.x

Type

public interface Type {  
    default String getTypeName() {
        return toString();
    }
}

提供了一个默认方法 getTypeName
Type
提供了 GenericArrayType ParameterizedType WildcardType TypeVariable 等子接口(忽略非 JDK 类)

GenericArrayType

public interface GenericArrayType extends Type {
    
    // 数组对应的 Type
    Type getGenericComponentType();
}

泛型数组,形如 Class<? extends T>[] T[] List<String>[]

ParameterizedType

public interface ParameterizedType extends Type {
  
  	// 获取参数的实际 Type 
    Type[] getActualTypeArguments();
    
    // 当前 Type 的实际类型,class 或者 interface
    Type getRawType();

	// 当前 Type 的所属 Type
    Type getOwnerType();
}

泛型参数,比如 Class<? extends T> T List<String>

WildcardType

public interface WildcardType extends Type {
    
    // 上界(extends)
    Type[] getUpperBounds();
   
   // 下界(Super)
    Type[] getLowerBounds();
}

表达式泛型,比如 ? extends T T super Class & Type

TypeVariable

public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {

	// 范型变量上界(未指明则为 Object)
    Type[] getBounds();

	// 声明该变量的类型
    D getGenericDeclaration();

    String getName();
    
    // 未知
    AnnotatedType[] getAnnotatedBounds();
}

泛型变量,比如 ? extends T 中的 T

示例 demo

借助以下 demo 演示这几个接口的关系

public class TestType<T extends TestType.UpperA & TestType.UpperB> {

    public @interface UpperA {

    }

    public interface UpperB {

    }

    Class<? extends T>[] clazz;

    /**
     * Class<? extends T>[]: GenericArrayType
     * Class<? extends T>: ParameterizedType
     * ? extends T: WildcardType
     * T: TypeVariable
     */
    @Test
    public void test1() throws NoSuchFieldException {
        Field field = TestType.class.getDeclaredField("clazz");
        Type type = field.getGenericType();

        if (type instanceof GenericArrayType) {
            Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
            System.out.println("GenericArrayType: " + genericComponentType);

            if (genericComponentType instanceof ParameterizedType) {
                Type ownerType = ((ParameterizedType) genericComponentType).getOwnerType();
                Type rawType = ((ParameterizedType) genericComponentType).getRawType();
                Type[] actualTypeArguments = ((ParameterizedType) genericComponentType).getActualTypeArguments();

                System.out.println("    ParameterizedType:");
                System.out.println("        ownerType: " + ownerType);
                System.out.println("        rawType: " + rawType);
                System.out.println("        actualTypeArguments: " + actualTypeArguments);

                for (Type t : actualTypeArguments) {
                    if (t instanceof WildcardType) {
                        Type[] lowerBounds = ((WildcardType) t).getLowerBounds();
                        Type[] upperBounds = ((WildcardType) t).getUpperBounds();

                        System.out.println("        WildcardType:");
                        System.out.println("            lowerBounds: ");
                        for (Type tt : lowerBounds) {
                            System.out.println("            " + tt.getTypeName());

                            handle(tt);
                        }

                        System.out.println("            upperBounds: ");
                        for (Type tt : upperBounds) {
                            System.out.println("            " + tt.getTypeName());

                            handle(tt);
                        }
                    }
                }
            }
        }
    }

    private void handle(Type tt) {
        if (tt instanceof TypeVariable) {
            GenericDeclaration genericDeclaration = ((TypeVariable) tt).getGenericDeclaration();
            Type[] bounds = ((TypeVariable) tt).getBounds();

            System.out.println("                TypeVariable");
            System.out.println("                    genericDeclaration: " + genericDeclaration);
            System.out.println("                    bounds:");
            for (Type ttt : bounds) {
                System.out.println("                        " + ttt.getTypeName());
            }
        }
    }
}

结果:
GenericArrayType: java.lang.Class<? extends T>
    ParameterizedType:
        ownerType: null
        rawType: class java.lang.Class
        actualTypeArguments: [Ljava.lang.reflect.Type;@7d4793a8
        WildcardType:
            lowerBounds: 
            upperBounds: 
            T
                TypeVariable
                    genericDeclaration: class com.xsn.type.TestType
                    bounds:
                        com.xsn.type.TestType$UpperA
                        com.xsn.type.TestType$UpperB

可以看到,形如 Class<? extends T>[] clazz 的变量

  • 变量本身是一个 GenericArrayType泛型数组
  • Class<? extends T>ParameterizedType参数泛型
  • ? extends TWildcardType表达式泛型
  • TTypeVariable泛型变量

ResolvableType

SpringType 的封装,内部大量借助此类来访问 Type 属性,包括 泛型 等,以 示例demo 演示

public class TestResolverType {

    class Sample<T> {

        List<? super T> list;

        private HashMap<Integer, List<String>> myMap;

        @Bean
        public T a(int a, T t) {

            return  null;
        }
    }

    @Test
    public void test1() throws NoSuchFieldException {
        ResolvableType t1 =
                ResolvableType.forType(Sample.class);
        handleGenerics(t1);

        ResolvableType t2 = ResolvableType.forField(
               Sample.class.getDeclaredField("list")
        );
        handleGenerics(t2);

        ResolvableType t3 = ResolvableType.forField(
                Sample.class.getDeclaredField("myMap")
        );
        handleGenerics(t3);

    }

    private void handleGenerics(ResolvableType t) {
        System.out.println(t.getType().getTypeName() + ":");

        System.out.println("    getRawClass = " + t.getRawClass());
        System.out.println("    getClass = " + t.getClass());
        System.out.println("    getSource = " + t.getSource());
        System.out.println("    getSuperType = " + t.getSuperType());

        System.out.println("    asMap = " + t.asMap());
        System.out.println("    asCollection = " + t.asCollection());

        System.out.println("    getGeneric(0).resolve() = " + t.getGeneric(0).resolve());
        System.out.println("    getGeneric(1).resolve() = " + t.getGeneric(1).resolve());
        System.out.println("    getGeneric(0) = " + t.getGeneric(0));
        System.out.println("    resolveGeneric(0, 1) = " + t.resolveGeneric(0, 1));
    }
}

结果:
com.xsn.type.TestResolverType$Sample:
    getRawClass = class com.xsn.type.TestResolverType$Sample
    getClass = class org.springframework.core.ResolvableType
    getSource = class com.xsn.type.TestResolverType$Sample
    getSuperType = java.lang.Object
    asMap = ?
    asCollection = ?
    getGeneric(0).resolve() = null
    getGeneric(1).resolve() = null
    getGeneric(0) = ?
    resolveGeneric(0, 1) = null
java.util.List<? super T>:
    getRawClass = interface java.util.List
    getClass = class org.springframework.core.ResolvableType
    getSource = java.util.List com.xsn.type.TestResolverType$Sample.list
    getSuperType = ?
    asMap = ?
    asCollection = java.util.Collection<?>
    getGeneric(0).resolve() = null
    getGeneric(1).resolve() = null
    getGeneric(0) = ?
    resolveGeneric(0, 1) = null
java.util.HashMap<java.lang.Integer, java.util.List<java.lang.String>>:
    getRawClass = class java.util.HashMap
    getClass = class org.springframework.core.ResolvableType
    getSource = private java.util.HashMap com.xsn.type.TestResolverType$Sample.myMap
    getSuperType = java.util.AbstractMap<java.lang.Integer, java.util.List<java.lang.String>>
    asMap = java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>
    asCollection = ?
    getGeneric(0).resolve() = class java.lang.Integer
    getGeneric(1).resolve() = interface java.util.List
    getGeneric(0) = java.lang.Integer
    resolveGeneric(0, 1) = null

总结

本章节简单介绍了 javaTypeSpringResolvableType,之后遇到就不会很陌生了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值