JAVA 反射(一)基礎(chǔ)

理解:

在運(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);

  } 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容