SPRING源码分析--ResolvableType
Posted BLACK CAT JAVA
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRING源码分析--ResolvableType相关的知识,希望对你有一定的参考价值。
SPRING源码分析--ResolvableType
JDK的Type类型
Type:是对java数据类型的分类抽象
首先所有的数据类型的类型都是Type,Class就是实现Type的接口
类图如下:
public class TypeTest {
public static void main(String[] args) {
Type type = TypeTest.class;
System.out.println(type);
}
}
// 控制台输出: class TypeTest
// Class.isPrimitive(),
// Class是否为原始类型(boolean、char、byte、short、int、long、float、double)是返回true
class{
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
}
ParameterizedType 参数化类型 即泛型;例如:List<T>、Map<K,V>等带有参数化的对象;
public interface ParameterizedType extends Type{
//获取<> 里面的实际类型
Type[] getActualTypeArguments();
//获取<>前面的类型
Type getRawType();
//如果这个类型是某个所属,获取顶层所有者类型,反则返回为null
//表示此类型是其成员之一的类型。例如,如果此类型为 O<T>.I<S>,则返回 O<T> 的表示形式。
//如果此类型为顶层类型,则返回 null。
Type getOwnerType();
}
public class ParameterizedTypeDemo{
public static void main(String[] args) {
List<Integer> foo = new ArrayList<Integer>(){};
Type mySuperClass = foo.getClass().getGenericSuperclass();
Type pType = ((ParameterizedType)mySuperClass).getActualTypeArguments()[0];
System.out.println(pType);
Type rawType = ((ParameterizedType) mySuperClass).getRawType();
System.out.println(rawType);
Type ownerType = ((ParameterizedType) mySuperClass).getOwnerType();
System.out.println(ownerType);
}
}
//控制台输出:
//class java.lang.Integer
//class java.util.ArrayList
//null
TypeVariable:代表泛型中的变量,比如下面的T就是TypeVariable类型
public interface TypeVariable<D extends GenericDeclaration> extends Type{
//获取泛型的上限,默认为object
Type[] getBounds();
//获取声明该变量实体(即获取类、方法、构造器)
D getGenericDeclaration();
//获取名称,即D,K,V,E之类的名称
String getName();
}
public class TypeVariableTest<T extends Number & Serializable> {
private T t;
public static void main(String[] args) throws NoSuchFieldException {
Field field = TypeVariableTest.class.getDeclaredField("t");
TypeVariable typeVariable = (TypeVariable) field.getGenericType();
Type[] types = typeVariable.getBounds();
for (Type type : types) {
System.out.println(type);
}
System.out.println(typeVariable.getName());
System.out.println(typeVariable.getGenericDeclaration());
}
}
//控制台输出
//class java.lang.Number
//interface java.io.Serializable
//T
//class com.black.cat.TypeVariableTest
WildcardType:代表泛型上界和下界。
List<? extends Fruit>定义了上界,?类型是Fruit的子类List<? super Apple>定义了下界,?类型是Apple的父类
public interface WildcardType extends Type {
//获取上界
Type[] getUpperBounds();
//获取下界
Type[] getLowerBounds();
}
public class WildcardTypeTest {
private List<? extends String> listStr;
private List<? super String> b;
public static void testGetBounds(String field) throws NoSuchFieldException {
Field fieldNum = WildcardTypeTest.class.getDeclaredField(field);
Type typeNum = fieldNum.getGenericType();
ParameterizedType parameterizedTypeTypeNum = (ParameterizedType) typeNum;
Type[] typesNum = parameterizedTypeTypeNum.getActualTypeArguments();
WildcardType wildcardType = (WildcardType) typesNum[0];
{
Type[] types = wildcardType.getUpperBounds();
for (Type type : types) {
System.out.println("upper:"+type);
}
types = wildcardType.getLowerBounds();
for (Type type : types) {
System.out.println("lower:"+type);
}
}
}
public static void testGetUpperBounds() throws NoSuchFieldException
{
testGetBounds("listStr");
testGetBounds("b");
}
public static void main(String[] args) throws NoSuchFieldException {
testGetUpperBounds();
}
}
//控制台输出
//upper:class java.lang.String
//upper:class java.lang.Object
//lower:class java.lang.String
GenericArrayType:泛型数组
public interface GenericArrayType extends Type {
//获取这个数组的元素类型
Type getGenericComponentType();
}
public class GenericArrayTypeBean <T> {
// 属于 GenericArrayType
List<String>[] pTypeArray;
// 属于 GenericArrayType
T[] vTypeArray;
// 不属于 GenericArrayType
List<String> list;
// 不属于 GenericArrayType
String[] strings;
public static void testGetBounds(String field) throws NoSuchFieldException {
Field fieldNum = GenericArrayTypeBean.class.getDeclaredField(field);
Type typeNum = fieldNum.getGenericType();
if(typeNum instanceof GenericArrayType){
GenericArrayType genericArrayType = (GenericArrayType) typeNum;
System.out.println(genericArrayType.getGenericComponentType());
}else {
System.out.println("不属于GenericArrayType:"+typeNum);
}
}
public static void testGetUpperBounds() throws NoSuchFieldException
{
testGetBounds("pTypeArray");
testGetBounds("vTypeArray");
testGetBounds("list");
testGetBounds("strings");
}
public static void main(String[] args) throws NoSuchFieldException {
testGetUpperBounds();
}
//控制台输出
//java.util.List<java.lang.String>
// T
//不属于GenericArrayType:java.util.List<java.lang.String>
//不属于GenericArrayType:class [Ljava.lang.String;
}
Type的获取方式
通过Class获取Type
getSuperclass 返回直接继承的父类,getGenericSuperclass 返回直接继承的父类(包含泛型参数)
public class Test {
class Person<T> {
}
class Student extends Person<Test> {
}
public static void main(String[] args) {
System.out.println("Student.class.getSuperclass()\n"
+ Student.class.getSuperclass());
System.out.println("Student.class.getGenericSuperclass()\n"
+ Student.class.getGenericSuperclass());
}
}
//控制台输出
//Student.class.getSuperclass()
//class com.black.cat.Test$Person
//Student.class.getGenericSuperclass()//com.black.cat.Test.com.black.cat.Test$Person<com.black.cat.Test>
通过Field获取Type
getType和getGenericType方法
public class FieldTest {
class Person<T> {
public List<CharSequence> charSequenceList;
public String str;
}
class Student extends Person<FieldTest> {
}
public static void main(String[] args) throws NoSuchFieldException {
Field field = Student.class.getField("str");
System.out.println(field.getType());
System.out.println(field.getGenericType());
Field charField = Student.class.getField("charSequenceList");
System.out.println(charField.getType());
System.out.println(charField.getGenericType());
}
}
//控制台输出
//class java.lang.String
//class java.lang.String
//interface java.util.List
//java.util.List<java.lang.CharSequence>
通过Method获取参数Type
Method是获取其参数或者返回值的Type,还有一个特殊的构造函数也可以归类为Method
public class MethodTest {
static class Person<T> {
}
static class Student extends Person<MethodTest> {
public Student(List<CharSequence> list) {
}
public Integer test(List<MethodTest> list) {
return null;
}
}
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Method method = Student.class.getMethod("test", List.class);
Class type1 = method.getParameterTypes()[0];
Type type2 = method.getGenericParameterTypes()[0];
System.out.println(type1);
System.out.println(type2);
Constructor constructor = Student.class.getConstructor(List.class);
Class type3 = constructor.getParameterTypes()[0];
Type type4 = constructor.getGenericParameterTypes()[0];
System.out.println(type3);
System.out.println(type4);
}
}
//控制台输出
//interface java.util.List
//java.util.List<com.black.cat.MethodTest>
//interface java.util.List
//java.util.List<java.lang.CharSequence>
MethodParameter
Spring对方法的参数做了一个抽象封装,如参数和返回值都可以认为是一个MethodParameter可以使用MethodParameter.forMethodOrConstructor静态方法来构建一个MethodParameter
public class MethodParameterTests {
public static class TestItem {
public TestItem(List<String> list) {
}
public void m1(List<Integer> intParam) {
}
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = TestItem.class.getMethod("m1", List.class);
MethodParameter parameter = MethodParameter.forMethodOrConstructor(method, 0);
System.out.println(parameter.getParameterType());
System.out.println(parameter.getGenericParameterType());
Constructor constructor = TestItem.class.getConstructor(List.class);
MethodParameter param = MethodParameter.forMethodOrConstructor(constructor, 0);
System.out.println(param.getParameterType());
System.out.println(param.getGenericParameterType());
}
}
//控制台输出
//interface java.util.List
//java.util.List<java.lang.Integer>
//interface java.util.List
//java.util.List<java.lang.String>
ResolvableType
ResolvableType是对Java类型的封装,提供了对父类(getSuperType())、接口(getInterfaces())、泛型参数(getGeneric(int...))的访问,最底层的实现为resolve()方法。ResolvableType可以通过forField(Field)、forMethodParameter(Method, int)、forMethodReturnType(Method)和forClass(Class)进行构造。这个类的大部分方法返回的都是ResolvableType类型,用户很容易地进行操作。
private HashMap<Integer, List<String>> myMap;
public void example() {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>
t.asMap(); // Map<Integer, List<String>>
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
t.resolveGeneric(1, 0); // String
}
造获取 Field 的泛型信息
ResolvableType.forField(Field)
static class Fields<T> {
public List<T> parameterizedType;
}
@Test
public void resolveParameterizedType() throws Exception {
ResolvableType type = ResolvableType.forField(Fields.class.getField("parameterizedType"));
assertThat(type.resolve(), equalTo((Class) List.class));
}
构造获取 Method 的泛型信息
ResolvableType.forMethodParameter(Method, int)
interface Methods<T> {
void typedParameter(T p);
}
@Test
public void resolveTypeVariableFromMethodParameter() throws Exception {
Method method = Methods.class.getMethod("typedParameter", Object.class);
ResolvableType type = ResolvableType.forMethodParameter(method, 0);
assertThat(type.getType().toString(), equalTo("T"));
}
构造获取方法返回参数的泛型信息
ResolvableType.forMethodReturnType(Method)
interface Methods<T> {
T typedReturn();
}
@Test
public void resolveTypeVariableFromMethodReturn() throws Exception {
Method method = Methods.class.getMethod("typedReturn");
ResolvableType type = ResolvableType.forMethodReturnType(method);
assertThat(type.getType().toString(), equalTo("T"));
}
构造获取构造参数的泛型信息
ResolvableType.forConstructorParameter(Constructor, int)
static class Constructors<T> {
public Constructors(List<CharSequence> p) {
}
public Constructors(Map<T, Long> p) {
}
}
@Test
public void forConstructorParameter() throws Exception {
Constructor<Constructors> constructor = Constructors.class.getConstructor(List.class);
ResolvableType type = ResolvableType.forConstructorParameter(constructor, 0);
assertThat(type.getType(), equalTo(constructor.getGenericParameterTypes()[0]));
}
构造获取类的泛型信息
ResolvableType.forClass(Class)
static class ExtendsList extends ArrayList<CharSequence> {
}
public static void main(String[] args)throws Exception {
ResolvableType type = ResolvableType.forClass(ExtendsList.class);
System.out.println(type);
assertThat(type.getType(), equalTo((Type) ExtendsList.class));
assertThat(type.getRawClass(), equalTo(ExtendsList.class));
assertTrue(type.isAssignableFrom(ExtendsList.class));
assertFalse(type.isAssignableFrom(ArrayList.class));
}
public static ResolvableType forClass(@Nullable Class<?> clazz) {
return new ResolvableType(clazz);
}
//com.black.cat.ResolvableTypeTests$ExtendsList
构造获取类型的泛型信息
ResolvableType.forType(Type)
interface Methods<T> {
T typedReturn();
}
@Test
public void resolveTypeVariableFromType() throws Exception {
Type sourceType = Methods.class.getMethod("typedReturn").getGenericReturnType();
ResolvableType type = ResolvableType.forType(sourceType);
assertThat(type.getType().toString(), equalTo("T"));
}
构造获取实例的泛型信息
ResolvableType.forInstance(Object)
@Test
public void forInstanceNoProvider() {
ResolvableType type = ResolvableType.forInstance(new Object());
assertThat(type.getType(), equalTo(Object.class));
assertThat(type.resolve(), equalTo(Object.class));
}
以上是关于SPRING源码分析--ResolvableType的主要内容,如果未能解决你的问题,请参考以下文章