1. 程式人生 > >Java 反射技術

Java 反射技術

一: 反射技術:動態的獲取指定的類以及動態的呼叫類中的內容 動態:類不確定 其實就是,在你還沒有建立這個類的時候就用這個類建立物件,使用方法,這能大大的提高程式的擴充套件性。 應用場景:在一個完全寫好的程式中你要再擴充套件功能,用之前的知識,肯定是,源程式留一個介面,在外部建立一個類實現介面,並且,在程式中建立實現類的物件呼叫方法,BUT, 你沒有原始碼,也就是說你無法在原始碼中操作,此時就要用到反射,在程式的配置檔案中,寫好類的名字,在程式中建立類的物件(這是在寫程式的時候乾的)。這就是在類不確定(甚至不知有木有的情況下)使用類來建立物件。 // 二: .class 檔案是Java的執行檔案,來自於原始檔的編譯 .class(類檔案)中包含了,類的成員變數和方法 位元組碼檔案對應的類:在Java 中有專門描述位元組碼檔案的類Class(描述類檔案的類)

class Class{//位元組碼檔案對應的類
		Filed  filed ;//欄位(類中的成員變數)將欄位封裝成物件(修飾/名字/值)物件型別Filed
		Constructor cons;//將建構函式也封裝成物件(名字,引數列表。。)物件型別 Constructor
		Method method;   
		////將類中的這些成員都封裝成物件,變成Class 類的成員。並且提供了對這些成員的操作
		getFiled();
		getMethod();
		getConstructor();
		//...
}

三: 電腦中 .class 檔案(儲存的是編譯後的相應類的二進位制檔案)————>Java 中描述.class 二進位制檔案的類 Class(位元組碼檔案的類)————>Java 中物件的建立依賴的就是.class 二進位制檔案

如何獲取位元組碼檔案的類:程式中的物件是依賴於.class 檔案建立的,所以通過物件來獲取 1.getClass(); //獲取位元組碼檔案的類,但是前提是:有類對應的物件

Person person = new Person();
Class class = person.getClass();

2.使用資料型別的靜態屬性。class

Class class = Person.class;

3.方式三:通過Class 這個類中提供的方法 forName (通過給定的類名,得到位元組碼檔案物件),自動找對應的位元組碼檔案,載入到記憶體中

Class p = Class.forName("Reflect.Person");//類的名字要寫的完全,包名+類名
        //通過newInstance 方法建立位元組碼檔案對應表示的類的例項
        Object obj = p.newInstance();//不依賴於類,去建立類的例項。但是在這個程式寫好後必須要有類,不然執行時會出錯
        //這就是反射技術獲取類的位元組碼檔案物件的方式

四:常見異常解析: ClassNotFoundException:找不到類對應的位元組碼檔案 InstantiationException :初始化異常,如果類沒有提供空參建構函式,就會出現異常 IllegalAccessException:類提供了空參建構函式,但是許可權不夠也會報錯

五:如何根據指定的帶參建構函式建立物件

 Constructor con = p.getConstructor(String.class,int.class);
        Object ob = con.newInstance("Lisi",12);//通過構造器來建立物件

六:獲取位元組碼檔案物件中的成員 關於獲取位元組碼檔案物件的成員: getXXXX():獲取的是共有的getDeclaredXXX():獲取的是聲明瞭的

1.獲取欄位:位元組碼檔案物件.getField() //getDeclaredField() 對於私有的成員變數,是無法對他進行操作的,暴力訪問: field.setAccessible(true);修改許可權 修改值: field.set(obj,30); 獲取值:field.get(obj) // 2.獲取方法

 Method method = p.getMethod("show",int.class,String.class);
 method.invoke(obj,12,"Wangwu");

七:反射的應用: 反射的使用精華在於,在還沒有寫類的時候你可以使用類。然後你在封裝好的程式外面,在定義類,寫好相應的方法。可以完美的解決程式擴充功能這個需求 反射技術的亮點就是為已經寫好的程式擴充功能