关于 Type 和 ResolvableType
前言
Type: java.lang.reflect.Type
,java 中对所有 类型 的顶层抽象,所谓类型,即 Class、泛型数组、参数类型、参数类型 等
ResolvableType: org.springframework.core.ResolvableType
,Spring 对 Type 的封装,提供对 Type 的访问方法
版本
JDK11
Spring 5.2.x
Type
public interface Type {
default String getTypeName() {
return toString();
}
}
提供了一个默认方法 getTypeName
提供了 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 T
即 WildcardType,表达式泛型T
即 TypeVariable,泛型变量
ResolvableType
Spring 对 Type 的封装,内部大量借助此类来访问 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
总结
本章节简单介绍了 java 的 Type 和 Spring 的 ResolvableType,之后遇到就不会很陌生了~