天天看點

Java反射機制,反射機制原理,學習與記錄

JAVA反射機制,先看下百度百科解釋

百度百科:

JAVA反射機制是在運作狀态中,對于任意一個實體類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動态擷取資訊以及動态調用對象方法的功能稱為java語言的反射機制。

JAVA反射(放射)機制:“程式運作時,允許改變程式結構或變量類型,這種語言稱為動态語言”。從這個觀點看,Perl,Python,Ruby是動态語言,C++,Java,C#不是動态語言。但是JAVA有着一個非常突出的動态相關機制:Reflection,用在Java身上指的是我們可以于運作時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程式可以加載一個運作時才得知名稱的class,獲悉其完整構造(但不包括methods定義),并生成其對象實體、或對其fields設值、或喚起其methods。

簡單了解

通俗來講:就是java檔案編譯成class檔案後,jvm運作後将class檔案讀取并把它們加入到記憶體中,每個class配置設定了一個class對象(有且隻有一個即:後面執行個體化的對象都是同一個class對象)。在java.lang.Class 這個類中提供了一些方法來擷取這些class對象中的成員變量、屬性、方法等。

擷取方式

其中第3種方式用得較多,如:JDBC加載資料庫驅動用到。

  1. Object ——> getClass(); 用父類Object建立。
  2. 類.class屬性擷取,如:Class userClass = User.class;
  3. Class userClass= Class.forName(“com.User”);//注意此字元串必須是真實路徑(包路徑.類),

常用方法

  • 1.加載

    Class class= Class.forName(“com.User”);

構造方法:
  • 2.擷取所有公有構造方法

    Constructor[] conArray = class.getConstructors();

  • 3.擷取所有的構造方法(包括:私有、受保護、預設、公有)

    conArray = class.getDeclaredConstructors();

    for(Constructor c : conArray){

    System.out.println©;

    }

  • 4.擷取公有、無參的構造方法

    Constructor con = class.getConstructor();

    //調用構造方法

    Object obj = con.newInstance();

  • 5.擷取私有構造方法,并調用

    con = class.getDeclaredConstructor(char.class);

    //調用構造方法

    con.setAccessible(true);//暴力通路(忽略掉通路修飾符)

    obj = con.newInstance(‘A’);

成員變量:
  • 6.擷取所有公有的字段

    Field[] fieldArray = stuClass.getFields();

    for(Field f : fieldArray){

    System.out.println(f);

    }

  • 7.擷取所有的字段(包括私有、受保護、預設的)

    fieldArray = class.getDeclaredFields();

    for(Field f : fieldArray){

    // 擷取字段中帶有某個注解屬性(可用于自定義注解,如擷取導出字段相關屬性用于導入導出,ExcelAnnotation :自定義excel注解)

    ExcelAnnotation excelAnnotation = f

    .getAnnotation(ExcelAnnotation.class);

    if (excelAnnotation != null) {

    System.out.println(f+" 字段帶有ExcelAnnotation 注解屬性");

    }

    System.out.println(f);

    }

  • 8.擷取公有字段,并調用

    Field f = class.getField(“name”);

    System.out.println(f);

    //擷取一個對象

    Object obj = class.getConstructor().newInstance();// 相當于new User()

    //為字段設定值

    f.set(obj, “李四”);

  • 9.擷取私有字段,并調用

    f = class.getDeclaredField(“phoneNum”);

    System.out.println(f);

    f.setAccessible(true);//暴力反射,解除私有限定

    f.set(obj, “18888889999”);

擷取成員方法并調用:
  • 10.擷取所有的”公有“方法

    Method[] methodArray = class.getMethods();

    for(Method m : methodArray){

    System.out.println(m);

    }

  • 11.擷取所有的方法,包括私有的

    Method[] methodArray = class.getDeclaredMethods();

  • 12.擷取公有的test()方法

    Method m = class.getMethod(“test”, String.class);

    System.out.println(m);

  • 13.擷取私有的test2()方法

    m = class.getDeclaredMethod(“test2”, int.class);//int.class是參數類型

    System.out.println(m);

    m.setAccessible(true);//解除私有限定

    Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(擷取有反射),一個是實參

    System.out.println(“傳回值:” + result);

  • 14.調用某個類的某個方法

    public void Test(String s){

    System.out.print(“Test方法被調用”+s);

    }

    //通過反射擷取Class對象

    Class class= Class.forName(“cn.com.test.User”);

    //2擷取Test()方法

    Method m = class.getMethod(“Test”);

    //3.調用Test()方法

    m.invoke(class.getConstructor().newInstance(),“是我調用的”);