理解:
在運(yùn)行期,獲取類的信息,包括構(gòu)造方法,字段,名字等類信息。
共同點(diǎn): get.xxxs 獲取公開的xxx數(shù)組
getDeclaredxxxs 獲取所有的xxx數(shù)組(包括私有的)
獲取單個(gè)同理。
構(gòu)造方法 Constructor
獲取途徑
設(shè)獲取了Class對象Class c = String.class
獲取所有公開的構(gòu)造方法class.getConstructors() 返回一個(gè)Constructor
數(shù)組。
獲取單個(gè)公開的構(gòu)造函數(shù),聲明函數(shù)的參數(shù)就行了(如果B繼承A,C繼承B,有fun(A),fun(B),我們給了個(gè)C參數(shù),會(huì)調(diào)用fun(B)) getConstructor(Class<?>... parameterTypes)
如果constructor參數(shù)是個(gè)泛型參數(shù),如果這個(gè)類對象其他constructor參數(shù)數(shù)量相同,會(huì)優(yōu)先調(diào)用其它的constructor。
獲取所有的構(gòu)造方法(包括私有的)getDeclaredConstructors()
獲取單個(gè)構(gòu)造方法(包括私有的)getDeclaredConstructor(Class<?>... parameterTypes)
通過構(gòu)造方法獲取類
調(diào)用Constructor對象的newInstance(Object... initargs)
實(shí)例
`String s = String.class.Constructor(Integer.class).newInstance(123);
字段 Field
類似的獲取方式。
特殊的操作:
可以獲取或設(shè)置對象上字段的值,如果要訪問為public的字段,要先設(shè)置訪問權(quán)限。
setAccessible(boolean flag),只是在此可訪問,并不會(huì)實(shí)際改變字段的權(quán)限(private還是pivate)
獲取
get(Object obj) 返回指定對象上此 Field 表示的字段的值。
設(shè)置
set(Object obj, Object value) 將指定對象變量上此 Field 對象表示的字段設(shè)置為指定的新值。
方法 Method
如果要執(zhí)行非共有的方法,也是要先setAccessible(true);
特殊操作:
方法當(dāng)然時(shí)用來執(zhí)行的。
Object invoke(Object obj, Object... args) obj是需要執(zhí)行這個(gè)方法的對象,如果是靜態(tài)方法,obj可設(shè)置為null,返回的是函數(shù)執(zhí)行的返回值。
返回類型獲取
返回類型的類信息
Class returnTypeClass = fun.getReturnType()
注解 Annotation
只有設(shè)置了運(yùn)行時(shí)處理的注解才可一被獲取到
方法,類,字段都可以獲取注解
getDeclaredAnnotation()也獲取不到非運(yùn)行注解。
獲取所有 getAnnotations();
獲取單個(gè)getAnnotation(Class Annotation)
查看注解某個(gè)函數(shù)值 假設(shè)注解有以下函數(shù)String value(),String name()獲取name的值:annotion.name()
典型代碼
//XXX為可以獲取注解的類
XXX xx=...;
Annotation[] as = xx.getAnnotations();
for(Annotation a : as)
{
// 如果注解時(shí)annotationA類型的
if(a instanceof annotationA)
(annotationA)a.AAA(); //類型轉(zhuǎn)換成A類型的,調(diào)用AAA的方法。
}
數(shù)組
創(chuàng)建新數(shù)組 int[] intArray = (int[]) Array.newInstance(int.class, 0x10);
設(shè)置數(shù)組某一項(xiàng)的值 Array.set(intArray, 0, 1);
獲取某一項(xiàng)的值 int i = (int)Array.get(intArray, 0))
獲取數(shù)組類信息Class c = int[].class;
其中Class中有判斷是否是數(shù)組的方法c.isArray()
獲取數(shù)組組件的class類型c.getComponentType()
示范代碼
// Create
int[] intArray = (int[]) Array.newInstance(int.class, 0x10);
// Set
Array.set(intArray, 0, 1);
Array.set(intArray, 1, 2);
Array.set(intArray, 2, 3);
// Get & Print
System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
System.out.println("intArray[2] = " + Array.get(intArray, 2));
// 獲取數(shù)組的類屬性 判斷是不是數(shù)組
Class c = int[].class;
System.out.println(c.isArray());
System.out.println(c.getSimpleName());
if (c.isArray()) {
Class ComponetType = c.getComponentType();
System.out.println(ComponetType.getName());
}
泛型類型信息
泛型ParameterizedType是Type的子接口,通過Type[] getActualTypeArguments()獲取規(guī)范化的參數(shù)(比如List<String>規(guī)范化參數(shù)是String,List<List<String>>,規(guī)范化參數(shù)是List,可以遞歸操作)。
可以從任何定義泛型的地方獲取它的信息。
例子:方法的返回值是List<String>
如果返回類型是個(gè)泛型(比如List<String>)可以進(jìn)一步操作
泛型的意義就是把類型也給參數(shù)化,提供檢查機(jī)制。
//獲取泛型
Type returnType = getGenericReturnType();
if(returnType instanceof ParameterizedType){
//返回實(shí)際參數(shù)數(shù)組
Type[] getActualTypeArguments= (ParameterizedType)returnType.getActualTypeArguments()
//這里我們參數(shù)List<String>只有一層,所以可以不用遞歸操作
for(Type t: Type)
{
Class typeArgClass = (Class) t;
System.out.println("typeArgClass = " + typeArgClass);
}
}