Java學習筆記--反射

左墾發表於2017-05-23

一,類載入器
<1>程式要使用某個類時,如果該類還未被載入到記憶體中,則系統會通過載入,連線,初始化三步來實現對這個類進行初始化。
載入過程:
(1).載入
就是指將class檔案讀入記憶體,併為之建立一個Class物件.
任何類被使用時系統都會建立一個Class物件。
(2).連線
a.驗證是否有正確的內部結構,並和其他類協調一致
b.準備負責為類的靜態成員分配記憶體,並設定預設初始化值
c.解析將類的二進位制資料中的符號引用替換為直接引用
(3).初始化就是我們以前講過的初始化 執行某個主類

<2>類的載入時機
2.1 建立類的例項
2.2 訪問類的靜態變數,或者為靜態變數賦值
2.3 呼叫類的靜態方法
2.4 使用反射方式來強制建立某個類或介面對應的java.lang.Class物件
2.5 初始化某個類的子類
2.6 直接使用java.exe命令來執行某個主類
<3>載入器分類
a.根類載入器:也成為引導類載入器,負責載入Java的核心類,有Bootstrap,ClassLoader,在JDK中JRE的lib目錄下rt.jar檔案中
b.擴充套件類載入器:負責JRE的擴充套件目錄中jar包的載入,在JDK中JRE的lib目錄下的ext目錄
c.系統類載入器:負責在JVM啟動時載入來自java命令的class檔案
二,反射
1.反射定義
通過已知位元組碼檔案物件,使用該類中的成員,每個class位元組碼檔案會對應的生成一個該位元組碼檔案對應的位元組碼檔案物件。
2.獲取位元組碼檔案方法
A.Object類的getClass()方法
B.資料型別的靜態Class屬性
C.Class類的靜態方法forName(“所需類的完全限定名”)
程式碼實現:`

    import java.lang.reflect.Constructor;
    public class ConstructorDemo {
public static void main(String[] args) throws Exception {
    Class<?> c = Class.forName("com.yang_o1.Person");
    Constructor<?>[] cons = c.getConstructors();
    for (Constructor<?> con : cons) {
        System.out.println(con);//public com.yang_o1.Person()
    }

    System.out.println("---");
    Constructor<?>[] cons2 = c.getDeclaredConstructors();
    for (Constructor<?> con : cons2) {
        System.out.println(con);//所有宣告的構造方法
    }

    System.out.println("---");
    Constructor<?> con = c.getConstructor();
    System.out.println(con);//public com.yang_o1.Person()
    Object obj = con.newInstance();
    System.out.println(obj);

    System.out.println("---");
    Constructor<?> con2 = c.getDeclaredConstructor(String.class,int.class,String.class);
    con2.setAccessible(true);
    Object obj2 = con2.newInstance("陳奕迅", 45, "香港");
    System.out.println(obj2);//Person [name=陳奕迅, age=45, address=香港]

    System.out.println("---");
    Constructor<?> con3 = c.getDeclaredConstructor(String.class, int.class);
    con3.setAccessible(true);
    Object obj3 = con3.newInstance("張學友", 50);
    System.out.println(obj3);//Person [name=張學友, age=50, address=null]
}

}

3.通過反射獲取物件並使用物件
3.1步驟
獲得位元組檔案物件--通過位元組碼檔案物件建立物件--通過位元組碼檔案物件獲得所需結構體,成員變數,成員方法--設定是否允許對成員進行操作的開關--設定物件(如果有需要的話)
3.2用到的方法
public Constructor[] getConstructors() 獲取公共的構造方法
public Constructor[] getDeclaredConstructors() 獲取所有的構造方法(包括私有)
public Constructor getConstructor(Class... parameterTypes)
public T newInstance(Object... initargs)
public Field[] getFields()獲取公有的成員變數
public Field[] getDeclaredFields()獲取全部的成員變數,包括私有
public Field getDeclaredField(String name)傳入變數名稱返回指定的成員變數物件,包括私有
public Field getField(String name)傳入變數名稱返回指定的成員變數物件,僅可獲取共有的
public void set(Object obj,Object value)給一個物件的一個欄位設定值
public Method[] getMethods()獲取所有公共成員方法
public Method[] getDeclaredMethods()獲取所有成員方法,包括私有
public Method getMethod(String name, Class<?>... parameterTypes)
public Method getDeclaredMethod(String name,Class<?>... paameter)
Object invoke(Object obj, Object... args) 讓某一個物件使用這個方法,並且傳入引數
相關實現程式碼:

import java.lang.reflect.Constructor;

        public class ConstructorDemo {
public static void main(String[] args) throws Exception {
    Class<?> c = Class.forName("com.yang_01.Person");
    Constructor<?>[] cons = c.getConstructors();
    for (Constructor<?> con : cons) {
        System.out.println(con);//public com.yang_o1.Person()
    }

    System.out.println("---");
    Constructor<?>[] cons2 = c.getDeclaredConstructors();
    for (Constructor<?> con : cons2) {
        System.out.println(con);//所有宣告的構造方法
    }

    System.out.println("---");
    Constructor<?> con = c.getConstructor();
    System.out.println(con);//public com.yang_o1.Person()
    Object obj = con.newInstance();
    System.out.println(obj);

    System.out.println("---");
    Constructor<?>[] con1 = c.getDeclaredConstructors();
    for (Constructor<?> conse : con1) {
        System.out.println(conse);
    }

    System.out.println("---");
    Constructor<?> con2 = c.getDeclaredConstructor(String.class,int.class,String.class);
    con2.setAccessible(true);
    Object obj2 = con2.newInstance("陳奕迅", 45, "香港");
    System.out.println(obj2);//Person [name=陳奕迅, age=45, address=香港]

    System.out.println("---");
    Constructor<?> con3 = c.getDeclaredConstructor(String.class, int.class);
    con3. = con3.newInstance("張學友", 50);
    System.out.println(obj3);//Person [name=張學友, age=50,address=null]
}

}`

相關文章