JAVA學習筆記——反射

1.類加載器
  A.類加載器
    負責將.class文件加載到內在中,併爲之生成對應的Class對象。
    雖然我們不需要關心類加載機制,但是瞭解這個機制我們就能更好的理解程序的運行。
  B.類加載器的組成
    Bootstrap ClassLoader 根類加載器
    Extension ClassLoader 擴展類加載器
    Sysetm ClassLoader 系統類加載器
2.反射
  A .JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
  B .要想解剖一個類,必須先要獲取到該類的字節碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個字節碼文件對應的Class類型的對象.
  Class類:
    成員變量: Field
    構造方法: Constructor
    成員方法: Method
  C .獲取Class文件對象的方式:
    a.Object類的getClass()方法 p.getClass()
    b.數據類型的靜態屬性 Person.class
    c.Class類中的靜態方法
      public static Class forName(String className) ;//className是包名.類名
    
    注:一般使用第三種方式,因爲第三種返回的是一個字符串,而不是一個具體的類名,這樣可以把字符串配置到配置文件中去。
  
3.通過反射獲取構造方法並創建對象過程
   A.獲取字節碼文件:使用Class.forName()方法
    static Class< ?> forName(String className) :返回與帶有給定字符串名的類或接口相關聯的 Class 對象。
   B.獲取構造方法對象
     Constructor< T> getConstructor(Class< ?>… parameterTypes) :返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公共構造方法。
     Constructor< ?>[] getConstructors() :返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的所有公共構造方法
      Constructor< T> getDeclaredConstructor(Class< ?>… parameterTypes) :返回一個 Constructor 對象,該對象反映此 Class 對象所表示的類或接口的指定構造方法。
      Constructor< ?>[] getDeclaredConstructors() :返回 Constructor 對象的一個數組,這些對象反映此 Class 對象表示的類聲明的所有構造方法
   C.使用Constructor的newInstance()方法創建對象
      T newInstance(Object… initargs) :使用此 Constructor 對象表示的構造方法來創建該構造方法的聲明類的新實例,並用指定的初始化參數初始化該實例。
    如果想要獲取private構造方法對象,可以對Constructor對象先設置暴力訪問
      public void setAccessible(boolean flag) throws SecurityException :將此對象的 accessible 標誌設置爲指示的布爾值。值爲 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。

        //獲取字節碼對象
        Class c = Class.forName("cn.zsl.Person") ;

        //獲取帶參構造方法
        Constructor con = c.getDeclaredConstructor(String.class,int.class) ;

        //創建對象
        Object obj = con.newInstance("張三" , 25) ;

        System.out.println(obj);   //Person [name="張三" , age=25]

4.通過反射獲取成員變量過程
  A.獲取構造方法並創建對象
  B.通過字節碼Class對象的方法獲取成員變量
     Field getField(String name) :返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段。
     Field[] getFields() :返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的所有可訪問公共字段。
      Field getDeclaredField(String name) :返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。
      Field[] getDeclaredFields() :返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。
   C.通過Filed對象方法將指定對象變量上此Field對象表示的字段值設置爲指定的新值
     void set(Object obj, Object value) :將指定對象變量上此 Field 對象表示的字段設置爲指定的新值。
     如果要訪問對象的私有變量,也可以使用Field的暴力訪問
     public void setAccessible(boolean flag) throws SecurityException :將此對象的 accessible 標誌設置爲指示的布爾值。值爲 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。
     

        //獲取字節碼對象
        Class c = Class.forName("cn.zsl.Person") ;

        //獲取帶參構造方法
        Constructor con = c.getDeclaredConstructor() ;

        //創建對象
        Object obj = con.newInstance() ;

        //獲取單個成員變量
        Field nameField = c.getField("name") ;
        Field ageField = c.getField("age") ;

        //將指定對象變量上此Field對象表示的字段值設置爲指定的新值
        nameField.set(obj, "張三");
        Integer i= new Integer(25);
        ageField.set(obj, i);

        System.out.println(obj);   //Person [name="張三" , age=25]

5.通過反射獲取成員方法
  A.獲取構造方法並創建對象
  B.通過字節碼對象獲取方法對象
     Method getMethod(String name, Class< ?>… parameterTypes) :返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。
     Method[] getMethods() :返回一個包含某些 Method 對象的數組,這些對象反映此 Class 對象所表示的類或接口(包括那些由該類或接口聲明的以及從超類和超接口繼承的那些的類或接口)的公共 member 方法。
     Method getDeclaredMethod(String name, Class< ?>… parameterTypes) :返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法。 第一個參數表示方法名,第二個參數表示該方法的參數的class類型,無參方法則不需要第二個參數
    Method[] getDeclaredMethods() : 返回 Method 對象的一個數組,這些對象反映此 Class 對象表示的類或接口聲明的所有方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。
  C.通過方法對象調用對象的該方法
     Object invoke(Object obj, Object… args) :對帶有指定參數的指定對象調用由此 Method 對象表示的底層方法。 第一個參數表示要調用的對象,第二個參數表示調用該方法的實際參數。無參方法則不需要第二個參數

        // 獲取字節碼對象
        Class c = Class.forName("cn.zsl.Person");

        // 獲取帶參構造方法
        Constructor con = c.getDeclaredConstructor();

        // 創建對象
        Object obj = con.newInstance(null);

        // 獲取單個成員方法
        Method m = c.getMethod("show", String.class);

        // 調用對象的該方法,因爲不確定會返回什麼值,所以返回值用Object接收
        Object objString = (String)m.invoke(obj, "張三"); // =obj.show("張三")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章