反射基本使用

LiuJian-Android發表於2018-03-27

1、簡介

  • 定義:
    JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的以及動態呼叫物件的方法的功能稱為Java的反射機制。
  • 反射機制類:
 //類 
java.lang.Class;  
//構造方法 
java.lang.reflect.Constructor;
//類的成員變數    
java.lang.reflect.Field; 
//類的方法
java.lang.reflect.Method;
//訪問許可權
java.lang.reflect.Modifier;
複製程式碼

2、反射類

//通過Class類的靜態方法——forName()來實現
Class<?> clazz = Class.forName("com.liujian.reflectdemo.Person");
複製程式碼

3、反射建立物件

3.1 不帶帶引數構造

//Class物件呼叫newInstance()方法生成
Object obj = clazz.newInstance();
複製程式碼

3.2 帶引數構造

//物件獲得對應的Constructor物件,再通過該Constructor物件的newInstance()方法生成
//獲取指定宣告建構函式
Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
Object obj = constructor.newInstance(new Object[]{"liujian"});
複製程式碼

4、反射方法

4.1獲取所有方法

getMethods(): 獲取包括自身和繼承過來的所有的public方法   
Method[] methods = clazz.getMethods();

getDeclaredMethods():獲取自身類中所有的方法(不包括繼承的,和訪問許可權無關)     
Method[] methods = clazz.getDeclaredMethods();
複製程式碼

4.2獲取指定方法

  • 方法範圍
getMethod():表示呼叫指定的一個公共的方法(包括繼承的)     
getDeclaredMethod:表示呼叫指定的一個本類中的方法(不包括繼承的)
複製程式碼
  • 有無引數
//無參
getMethod(String methodName)
getDeclaredMethod(String name)
//有參
getMethod(String methodName,Class<>… parameterTypes)
getDeclaredMethod(String name,Class<>… parameterTypes)
引數:
    methodName: 表示被呼叫方法的名字
    parameterTypes:表示被呼叫方法的引數的Class型別如String.class
複製程式碼
  • 傳參形式
//直接寫引數形式
Method method = clazz.getMethod("run",String.class);
//陣列引數形式
Method method = clazz.getMethod("run",new class[]{String.class});
複製程式碼

5、反射屬性

//獲取class物件的所有屬性
Field[] allFields = clazz.getDeclaredFields();
//獲取class物件的public屬性
Field[] publicFields = clazz.getFields();
//獲取class指定屬性
Field ageField = clazz.getDeclaredField("age");
//獲取class指定的public屬性
Field desField = clazz.getField("des");
複製程式碼

6、呼叫反射方法

public Object invoke(Object obj,Object… args):表示呼叫當前Method所表示的方法
  引數:
        obj: 表示被呼叫方法底層所屬物件(呼叫靜態方法的時可以為nul)
             Method m = clz.getMethod("liujun",String.class);
        args:表示呼叫方法是傳遞的實際引數
  返回:
        底層方法的返回結果
        
//如果呼叫私有方法,應該設定該方法為可訪問的
method.setAccessible(true);
method.invoke(clazz,"liujian");
複製程式碼