【Spring源码分析】ResolvableType

【Spring源码分析】ResolvableType

参考
目录

文章目录

      • 【Spring源码分析】ResolvableType
          • 一、ParameterizedType 参数化类型,即泛型;例如:List< T>、Map< K,V>等带有参数化的对象;
          • 二、GenericArrayType—— 泛型数组 泛型数组,描述的是形如:A< T>[]或T[]类型变量和原始类型
          • 三、TypeVariable
          • 四、WildcardType
          • 五、获取父接口父类中的泛型参数,使用原生和spring ResolvableType

Type
在这里插入图片描述

所有类型的类型是常见的超接口Java编程语言。这些包括原始类型,参数化的类型,数组类型,类型变量和原始类型(These include raw types, parameterized types, array types, type variables and primitive types).它并不是我们平常工作中经常使用的 int、String、List、Map等数据类型,而是从Java语言角度来说,对基本类型、引用类型向上的抽象;

Type体系中类型的包括:原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)、基本类型(Class);

原始类型,不仅仅包含我们平常所指的类,还包括枚举、数组、注解等;
参数化类型,就是我们平常所用到的泛型List、Map;
数组类型,并不是我们工作中所使用的数组String[] 、byte[],而是带有泛型的数组,即T[] ;
基本类型,也就是我们所说的java的基本类型,即int,float,double等

一、ParameterizedType 参数化类型,即泛型;例如:List< T>、Map< K,V>等带有参数化的对象;

作用于Class的Field上面

Type[] getActualTypeArguments(); 返回 这个 Type 类型的参数的实际类型数组。

package com.lvyuanj.standard.resolvabletypes;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** ParameterizedType 使用测试 参数化类型**/
@Slf4j
public class ParameterizedTypeTest {/*** 1、map: 获取ParameterizedType:class java.lang.String* 2、map: 获取ParameterizedType:class com.wangji.demo.ParameterizedTypeTest* 3、map:getOwnerType is null* 4、map:getRawType:interface java.util.Map*/private Map<String, ParameterizedTypeTest> map;/*** 1、set1: 获取ParameterizedType:class java.lang.String* 2、set1:getOwnerType is null* 3、set1:getRawType:interface java.util.Set*/private Set<String> set1;/*** 1、 clz: 获取ParameterizedType:?* 2、 clz:getOwnerType is null* 3、clz:getRawType:class java.lang.Class*/private Class<?> clz;/*** 1、holder: 获取ParameterizedType:class java.lang.String* 2、holder:getOwnerType:class com.wangji.demo.ParameterizedTypeTest* 3、holder:getRawType:class com.wangji.demo.ParameterizedTypeTest$Holder*/private Holder<String> holder;/*** 1、list: 获取ParameterizedType:class java.lang.String* 2、list:getOwnerType is null* 3、list:getRawType:interface java.util.List*/private List<String> list;/*** str:is not ParameterizedType*/private String str;/*** i:is not ParameterizedType*/private Integer i;/*** set:is not ParameterizedType*/private Set set;/***  aList:is not ParameterizedType*/private List aList;/*** 1、entry: 获取ParameterizedType:class java.lang.String* 2、entry: 获取ParameterizedType:class java.lang.String* 3、entry:getOwnerType:interface java.util.Map* 4、entry:getRawType:interface java.util.Map$Entry*/private Map.Entry<String, String> entry;static class Holder<V> {}public static void testParameterizedType() {Field f = null;try {Field[] fields = ParameterizedTypeTest.class.getDeclaredFields();for (int i = 0; i < fields.length; i++) {f = fields[i];if(f.getName().equals("log")){continue;}System.out.println(f.getName()+" == " + f.getType());if(f.getGenericType() instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) f.getGenericType();for(Type type :parameterizedType.getActualTypeArguments()){log.info(f.getName()+": 获取ParameterizedType:"+type);}if(parameterizedType.getOwnerType() !=null){log.info(f.getName()+":getOwnerType:"+parameterizedType.getOwnerType());}else{log.info(f.getName()+":getOwnerType is null");}if(parameterizedType.getRawType() !=null){log.info(f.getName()+":getRawType:"+parameterizedType.getRawType());}}else{log.info(f.getName() + ":is not ParameterizedType ");}}}catch (Exception e){log.error("error",e);}}public static void main(String[] args) {testParameterizedType();}
}

运行结果如下:

map == interface java.util.Map
11:04:52.041 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - map: 获取ParameterizedType:class java.lang.String
11:04:52.047 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - map: 获取ParameterizedType:class com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest
11:04:52.047 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - map:getOwnerType is null
11:04:52.048 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - map:getRawType:interface java.util.Map
set1 == interface java.util.Set
11:04:52.049 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - set1: 获取ParameterizedType:class java.lang.String
11:04:52.049 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - set1:getOwnerType is null
11:04:52.049 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - set1:getRawType:interface java.util.Set
clz == class java.lang.Class
11:04:52.050 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - clz: 获取ParameterizedType:?
11:04:52.050 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - clz:getOwnerType is null
11:04:52.050 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - clz:getRawType:class java.lang.Class
holder == class com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest$Holder
11:04:52.051 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - holder: 获取ParameterizedType:class java.lang.String
11:04:52.051 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - holder:getOwnerType:class com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest
11:04:52.051 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - holder:getRawType:class com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest$Holder
list == interface java.util.List
11:04:52.051 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - list: 获取ParameterizedType:class java.lang.String
11:04:52.051 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - list:getOwnerType is null
11:04:52.052 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - list:getRawType:interface java.util.List
str == class java.lang.String
11:04:52.052 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - str:is not ParameterizedType 
i == class java.lang.Integer
11:04:52.052 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - i:is not ParameterizedType 
set == interface java.util.Set
11:04:52.052 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - set:is not ParameterizedType 
aList == interface java.util.List
11:04:52.052 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - aList:is not ParameterizedType 
entry == interface java.util.Map$Entry
11:04:52.053 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - entry: 获取ParameterizedType:class java.lang.String
11:04:52.053 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - entry: 获取ParameterizedType:class java.lang.String
11:04:52.053 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - entry:getOwnerType:interface java.util.Map
11:04:52.053 [main] INFO  com.lvyuanj.standard.resolvabletypes.ParameterizedTypeTest - entry:getRawType:interface java.util.Map$Entry
二、GenericArrayType—— 泛型数组 泛型数组,描述的是形如:A< T>[]或T[]类型变量和原始类型

作用于Class的method上面

package com.lvyuanj.standard.resolvabletypes;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.*;
import java.util.List;/*** GenericArrayType—— 泛型数组* 泛型数组,描述的是形如:A<T>[]或T[]类型*   is either a parameterized type or a type variable.*/
@Slf4j
public class GenericArrayTypeTest<T> {/*** 含有泛型数组的才是GenericArrayType* @param pTypeArray GenericArrayType type :java.util.List<java.lang.String>[];* genericComponentType:java.util.List<java.lang.String>* @param vTypeArray  GenericArrayType type :T[];genericComponentType:T* @param list ParameterizedType type :java.util.List<java.lang.String>;* @param strings type :class [Ljava.lang.String;* @param test type :class [Lcom.wangji.demo.GenericArrayTypeTest;*/public void testGenericArrayType(List<String>[] pTypeArray, T[] vTypeArray, List<String> list, String[] strings, GenericArrayTypeTest[] test) {}/*** 1、getGenericComponentType* 返回泛型数组中元素的Type类型,即List<String>[] 中的 List<String>(ParameterizedTypeImpl)* 、T[] 中的T(TypeVariableImpl);* 值得注意的是,无论是几维数组,getGenericComponentType()方法都只会脱去最右边的[],返回剩下的值;*/public static void testGenericArrayType() {Method[] declaredMethods = GenericArrayTypeTest.class.getDeclaredMethods();for(Method method :declaredMethods){if(method.getName().startsWith("main")){continue;}log.info("declare Method:"+method);/*** 获取当前参数所有的类型信息*/Type[] types = method.getGenericParameterTypes();for(Type type: types){if(type instanceof ParameterizedType){log.info("ParameterizedType type :"+type);}else if(type instanceof GenericArrayType){log.info("GenericArrayType type :"+type);Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();/*** 获取泛型数组中元素的类型,要注意的是:无论从左向右有几个[]并列,* 这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。*/log.info("genericComponentType:"+genericComponentType);}else if(type instanceof WildcardType){log.info("WildcardType type :"+type);}else if(type instanceof  TypeVariable){log.info("TypeVariable type :"+type);}else {log.info("type :"+type);}}}}public static void main(String[] args) {testGenericArrayType();}
}

运行结果:

11:31:23.706 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - declare Method:public void com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest.testGenericArrayType(java.util.List[],java.lang.Object[],java.util.List,java.lang.String[],com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest[])
11:31:23.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - GenericArrayType type :java.util.List<java.lang.String>[]
11:31:23.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - genericComponentType:java.util.List<java.lang.String>
11:31:23.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - GenericArrayType type :T[]
11:31:23.719 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - genericComponentType:T
11:31:23.719 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - ParameterizedType type :java.util.List<java.lang.String>
11:31:23.719 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - type :class [Ljava.lang.String;
11:31:23.719 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - type :class [Lcom.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest;
11:31:23.719 [main] INFO  com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest - declare Method:public static void com.lvyuanj.standard.resolvabletypes.GenericArrayTypeTest.testGenericArrayType()
三、TypeVariable

TypeVariable Interface TypeVariable< D extends GenericDeclaration>
在这里插入图片描述

泛型的类型变量,指的是List< T>、Map< K,V>中的T,K,V等值,实际的Java类型是TypeVariableImpl(TypeVariable的子类;此外,还可以对类型变量加上extend限定,这样会有类型变量对应的上限;值得注意的是,类型变量的上限可以为多个,必须使用&符号相连接,例如 List< T extends Number & Serializable>;其中,& 后必须为接口;

1、Type[] getBounds() 类型对应的上限,默认为Object
2、D getGenericDeclaration() 获取声明该类型变量实体,也就是TypeVariableTest< T>中的TypeVariableTest
3、String getName() 获取类型变量在源码中定义的名称;

package com.lvyuanj.standard.resolvabletypes;import lombok.extern.slf4j.Slf4j;import java.io.Serializable;
import java.lang.reflect.*;
import java.util.List;/*** Interface TypeVariable<D extends GenericDeclaration> , * D - the type of generic declaration that declared the underlying type variable.* 类型变量是类型变量的公共超接口。类型变量是第一次使用反射方法创建的,如在这个包中指定的。* 如果类型变量T由类型(即类、接口或注释类型)T引用,并且T由第n个封闭类T(参见JLS.1.2)来声明,* 那么T的创建需要T的第i个包围类的分辨率(参见JVMS 5),对于i=0到n,包含。创建类型变量不能导致其边界的创建。 * 重复创建类型变量没有任何效果。* <p>* 可以在运行时实例化多个对象以表示给定的类型变量。即使类型变量只创建一次, * 但这并不意味着缓存表示类型变量的实例的任何要求。* 但是,表示一个类型变量的所有实例必须是相等的()。因此,类型变量的用户不能依赖实现该接口的类实例的标识。* <p>* 泛型的类型变量,指的是List<T>、Map<K,V>中的T,K,V等值,实际的Java类型是TypeVariableImpl * (TypeVariable的子类); * 此外,还可以对类型变量加上extend限定,这样会有类型变量对应的上限;值得注意的是,类型变量的上限可以为多个, * 必须使用&符号相连接,例如 List<T extends Number & Serializable>;其中,& 后必须为接口;* 没有指定的话 ,V 的 上边界 属于  Object*/
@Slf4j
public class TypeVariableTest<T extends Number & Serializable, V> {/*** TypeVariable*/private T key;/*** TypeVariable*/private V value;/*** GenericArrayType V[]-> V TypeVariable 两种混合起来了*/private V[] values;/*** 原始类型,不仅仅包含我们平常所指的类,还包括枚举、数组、注解等;* 基本类型,也就是我们所说的java的基本类型,即int,float,double等*/private String str;/*** 获取ParameterizedType List<T> -> T TypeVariable 两种混合起来了*/private List<T> tList;/*** 从这个例子中可以看出来各种类型之间是相互在使用的* TypeVariable<D extends GenericDeclaration>* GenericDeclaration  All Known Implementing Classes: Class, Constructor, Method*/public static void testTypeVariableTest() {Field f = null;try {Field[] fields = TypeVariableTest.class.getDeclaredFields();for (int i = 0; i < fields.length; i++) {f = fields[i];if (f.getName().equals("log")) {continue;}log.info("begin ******当前field:" + f.getName() + " *************************");if (f.getGenericType() instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) f.getGenericType();for (Type type : parameterizedType.getActualTypeArguments()) {log.info(f.getName() + ": 获取ParameterizedType:" + type);if (type instanceof TypeVariable) {printTypeVariable(f.getName(), (TypeVariable) type);}}if (parameterizedType.getOwnerType() != null) {log.info(f.getName() + ":getOwnerType:" + parameterizedType.getOwnerType());} else {log.info(f.getName() + ":getOwnerType is null");}if (parameterizedType.getRawType() != null) {log.info(f.getName() + ":getRawType:" + parameterizedType.getRawType());}} else if (f.getGenericType() instanceof GenericArrayType) {GenericArrayType genericArrayType = (GenericArrayType) f.getGenericType();log.info("GenericArrayType type :" + genericArrayType);Type genericComponentType = genericArrayType.getGenericComponentType();if (genericComponentType instanceof TypeVariable) {TypeVariable typeVariable = (TypeVariable) genericComponentType;printTypeVariable(f.getName(), typeVariable);}} else if (f.getGenericType() instanceof TypeVariable) {TypeVariable typeVariable = (TypeVariable) f.getGenericType();printTypeVariable(f.getName(), typeVariable);} else {log.info("type :" + f.getGenericType());}log.info("end ******当前field:" + f.getName() + " *************************");}} catch (Exception e) {log.error("error", e);}}/*** 1、Type[] getBounds() 类型对应的上限,默认为Object* 2、D getGenericDeclaration()  获取声明该类型变量实体,也就是TypeVariableTest<T>中的TypeVariableTest* 3、String getName() 获取类型变量在源码中定义的名称;** @param fieldName* @param typeVariable*/private static void printTypeVariable(String fieldName, TypeVariable typeVariable) {for (Type type : typeVariable.getBounds()) {log.info(fieldName + ": TypeVariable getBounds " + type);}log.info("定义Class getGenericDeclaration: " + typeVariable.getGenericDeclaration());log.info("getName: " + typeVariable.getName());}public static void main(String[] args) {testTypeVariableTest();}}

运行结果

11:39:48.697 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - begin ******当前field:key *************************
11:39:48.708 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - key: TypeVariable getBounds class java.lang.Number
11:39:48.709 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - key: TypeVariable getBounds interface java.io.Serializable
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - 定义Class getGenericDeclaration: class com.lvyuanj.standard.resolvabletypes.TypeVariableTest
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - getName: T
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - end ******当前field:key *************************
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - begin ******当前field:value *************************
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - value: TypeVariable getBounds class java.lang.Object
11:39:48.711 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - 定义Class getGenericDeclaration: class com.lvyuanj.standard.resolvabletypes.TypeVariableTest
11:39:48.712 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - getName: V
11:39:48.712 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - end ******当前field:value *************************
11:39:48.712 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - begin ******当前field:values *************************
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - GenericArrayType type :V[]
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - values: TypeVariable getBounds class java.lang.Object
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - 定义Class getGenericDeclaration: class com.lvyuanj.standard.resolvabletypes.TypeVariableTest
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - getName: V
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - end ******当前field:values *************************
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - begin ******当前field:str *************************
11:39:48.713 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - type :class java.lang.String
11:39:48.714 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - end ******当前field:str *************************
11:39:48.716 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - begin ******当前field:tList *************************
11:39:48.717 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - tList: 获取ParameterizedType:T
11:39:48.717 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - tList: TypeVariable getBounds class java.lang.Number
11:39:48.717 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - tList: TypeVariable getBounds interface java.io.Serializable
11:39:48.717 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - 定义Class getGenericDeclaration: class com.lvyuanj.standard.resolvabletypes.TypeVariableTest
11:39:48.717 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - getName: T
11:39:48.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - tList:getOwnerType is null
11:39:48.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - tList:getRawType:interface java.util.List
11:39:48.718 [main] INFO  com.lvyuanj.standard.resolvabletypes.TypeVariableTest - end ******当前field:tList *************************
四、WildcardType

WildcardType represents a wildcard type expression, such as ?, ? extends Number, or ? super Integer.
通配符表达式,或泛型表达式,它虽然是Type的一个子接口,但并不是Java类型中的一种,表示的仅仅是类似 ? extends T、? super K这样的通配符表达式。 ?—通配符表达式,表示通配符泛型,但是WildcardType并不属于Java-Type中的一钟;例如:List< ? extends Number> 和 List< ? super Integer>;
1、Type[] getUpperBounds(); //获得泛型表达式上界(上限) 获取泛型变量的上边界(extends)
2、Type[] getLowerBounds(); //获得泛型表达式下界(下限) 获取泛型变量的下边界(super)

package com.lvyuanj.standard.resolvabletypes;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.*;
import java.util.List;/*** WildcardType represents a wildcard type expression, such as ?, ? extends Number,  * or ? super Integer.* 通配符表达式,或泛型表达式,它虽然是Type的一个子接口,但并不是Java类型中的一种,表示的仅仅是类似 *  ? extends T、? super K这样的通配符表达式。* ?---通配符表达式,表示通配符泛型,但是WildcardType并不属于Java-Type中的一钟; * 例如:List< ? extends Number> 和 List< ? super Integer>;* 1、Type[] getUpperBounds();  //获得泛型表达式上界(上限) 获取泛型变量的上边界(extends)* 2、Type[] getLowerBounds(); //获得泛型表达式下界(下限) 获取泛型变量的下边界(super)**/
@Slf4j
public class WildcardTypeTest {/*** 1、 a: 获取ParameterizedType:? extends java.lang.Number* 2、上界:class java.lang.Number*/private List< ? extends Number> a;/*** b: 获取ParameterizedType:? super java.lang.String*  上届:class java.lang.Object*  下届:class java.lang.String*/private List< ? super String> b;/*** c: 获取ParameterizedType:class java.lang.String*/private List<String> c;/*** aClass: 获取ParameterizedType:?* 上届:class java.lang.Object*/private Class<?> aClass;private String wangji;/*** 多种数据进行混合*/public static void testWildcardType() {Field f = null;try {Field[] fields = WildcardTypeTest.class.getDeclaredFields();for (int i = 0; i < fields.length; i++) {f = fields[i];if (f.getName().equals("log")) {continue;}log.info("begin ******当前field:" + f.getName() + " *************************");if (f.getGenericType() instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) f.getGenericType();for (Type type : parameterizedType.getActualTypeArguments()) {log.info(f.getName() + ": 获取ParameterizedType:" + type);if (type instanceof WildcardType) {printWildcardType((WildcardType) type);}}} else if (f.getGenericType() instanceof GenericArrayType) {GenericArrayType genericArrayType = (GenericArrayType) f.getGenericType();log.info("GenericArrayType type :" + genericArrayType);Type genericComponentType = genericArrayType.getGenericComponentType();if (genericComponentType instanceof WildcardType) {printWildcardType((WildcardType) genericComponentType);}} else if (f.getGenericType() instanceof TypeVariable) {TypeVariable typeVariable = (TypeVariable) f.getGenericType();log.info("typeVariable:" + typeVariable);} else {log.info("type :" + f.getGenericType());if (f.getGenericType() instanceof WildcardType) {printWildcardType((WildcardType) f.getGenericType());}}log.info("end ******当前field:" + f.getName() + " *************************");}} catch (Exception e) {log.error("error", e);}}private static void printWildcardType(WildcardType wildcardType) {for (Type type : wildcardType.getUpperBounds()) {log.info("上界:" + type);}for (Type type : wildcardType.getLowerBounds()) {log.info("下界:" + type);}}public static void main(String[] args) {testWildcardType();}
}

运行结果:

11:48:56.258 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - begin ******当前field:a *************************
11:48:56.287 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - a: 获取ParameterizedType:? extends java.lang.Number
11:48:56.287 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - 上界:class java.lang.Number
11:48:56.287 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - end ******当前field:a *************************
11:48:56.288 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - begin ******当前field:b *************************
11:48:56.288 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - b: 获取ParameterizedType:? super java.lang.String
11:48:56.288 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - 上界:class java.lang.Object
11:48:56.288 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - 下界:class java.lang.String
11:48:56.288 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - end ******当前field:b *************************
11:48:56.289 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - begin ******当前field:c *************************
11:48:56.289 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - c: 获取ParameterizedType:class java.lang.String
11:48:56.289 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - end ******当前field:c *************************
11:48:56.289 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - begin ******当前field:aClass *************************
11:48:56.290 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - aClass: 获取ParameterizedType:?
11:48:56.290 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - 上界:class java.lang.Object
11:48:56.291 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - end ******当前field:aClass *************************
11:48:56.291 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - begin ******当前field:wangji *************************
11:48:56.292 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - type :class java.lang.String
11:48:56.292 [main] INFO  com.lvyuanj.standard.resolvabletypes.WildcardTypeTest - end ******当前field:wangji *************************
五、获取父接口父类中的泛型参数,使用原生和spring ResolvableType
public class Parent<T> {
}public interface IParent<T> {
}

使用原生和spring ResolvableType的比较

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/689111.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索人工智能的深度神经网络:理解、应用与未来

深度神经网络&#xff08;DNNs&#xff09;是一种人工智能模型&#xff0c;其灵感来自于人脑神经元之间的连接。它们由多个层次组成&#xff0c;每一层都包含多个神经元&#xff0c;这些神经元通过权重连接在一起。信息通过网络的输入层传递&#xff0c;并经过一系列隐藏层&…

邂逅Linux--常见指令,万物为文件(一)

引子&#xff1a;在之前&#xff0c;我们经常听到Linux&#xff0c;那什么是Linux呢&#xff1f;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年10月5日首次发布&#xff…

RabbitMQ基础入门

初识MQ 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不能跟多个人同…

Verlog-流水灯-FPGA

Verlog-流水灯-FPGA 引言&#xff1a; ​ 随着电子技术的飞速发展&#xff0c;现场可编程门阵列&#xff08;FPGA&#xff09;已成为电子设计自动化&#xff08;EDA&#xff09;领域中不可或缺的组件。FPGA以其高度的灵活性和可定制性&#xff0c;广泛应用于通信、图像处理、工…

Python Supervisor助力代码后台运行

大家好&#xff0c;Supervisor 是一个 C/S 架构的进程监控与管理工具&#xff0c;本文将主要介绍其基本用法和部分高级特性&#xff0c;用于解决部署持久化进程的稳定性问题。 1.问题场景 在实际的工作中&#xff0c;往往会有部署持久化进程的需求&#xff0c;比如接口服务进…

【高阶数据结构】LRU Cache -- 详解

一、什么是 LRU Cache LRU&#xff08;Least Recently Used&#xff09;&#xff0c;意思是最近最少使用&#xff0c;它是一种 Cache 替换算法。 什么是 Cache&#xff1f; 狭义的 Cache 指的是位于 CPU 和主存间的快速 RAM&#xff0c;通常它不像系统主存那样使用 DRAM 技术&…

【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十三篇&#xff1a;volatile关键字讲解。 在 Java 中&#xff0c;volatile关键字是一种轻量级的同步机制&#xff0c;用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及…

商家转账到零钱开通揭秘,微信支付商户如何玩转分销返佣现金营销

在数字支付日益普及的今天&#xff0c;微信支付凭借其便捷、安全的特性&#xff0c;成为了众多商户的首选支付工具。而微信支付商户平台上的“商家转账到零钱”功能&#xff0c;更是为商户们打开了一扇全新的营销大门。今天&#xff0c;我们就来一起揭秘这个功能聊聊如何快速开…

Java入门基础学习笔记4——开发Helloworld入门程序

Java程序开发的三个步骤&#xff1a; 1&#xff09;编写代码 2&#xff09;编译代码 3&#xff09;运行代码 注意事项&#xff1a; 第一个java程序建议使用记事本来编写。 建议代码文件名全英文、首字母大写、满足驼峰模式&#xff0c;源代码文件的后缀必须是.java 注意&a…

【前端】桌面版docker并部署前端项目

环境 win10专业版 2004 , 需科学 官网下载安装包并安装4.29.0版本 终端输入 wsl --installdocker桌面版和模拟器只能选一个&#xff0c;不然一直转圈圈 镜像配置加速&#xff0c;在settings—>docker engine下 {"builder": {"gc": {"defaultKee…

ICode国际青少年编程竞赛- Python-4级训练场-列表综合练习

ICode国际青少年编程竞赛- Python-4级训练场-列表综合练习 1、 Flyer[3].step(1) Flyer[7].step(2) Flyer[11].step(1) for i in range(4):Flyer[i * 2].step(1) Flyer[8].step(3)for i in range(3):Dev.turnRight()Dev.step(-5)2、 for i in range(5):Flyer[i5].step(Flyer[…

【数据分析】 JupyterNotebook安装及使用简介

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 在数据分析中&#xff0c;一般用Pycharm编辑代…