黑馬程式設計師--java高新技術----反射
---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ----------------------
什麼是反射?
反射就是把一個類中的各種元素對映成一個類。
得到一個類中的元素都是從這個類的位元組碼中得到的。
所以要得到反射的物件,必須先得到這個類的位元組碼。
得到位元組碼有三種方式:
1. 物件.getClass();
String str = "abc";
str.getClass();
2. 類.class ;
String.class ;
3. Class.forName();
Class.forName("java.lang.String") ;
構造方法的反射:
反射就是把一個類中的各種元素對映成一個類。構造方法是類中的一個元素,所以可以反射為一個類。
這個類是Constructor類。一個構造方法對應一個Constructor物件。
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str1 = (String) constructor1.newInstance(new StringBuffer("abc"));
通過構造方法物件建立一個String物件。由於編譯時編譯器並不知道該構造方法物件對應的類是哪個,所以要進行型別轉換,告訴編譯器通過改構造方法得到的是一個String型別的物件。
newInstance()方法:
使用此
Constructor
物件表示的構造方法來建立該構造方法的宣告類的新例項,並用指定的初始化引數初始化該例項。
newInstance()方法的引數是一個物件。
構造方法的反射得到的物件具有構造方法的特性,也就是建立物件並例項化。
成員變數的反射:
成員變數反射用到的類是Field;
自己寫一個類來演示成員變數反射的用法。
Field fieldX = p1.getClass().getField("x");
fieldX不是物件的成員變數,而是類的成員變數。
如果要得到具體某一個物件的某個成員變數的值,則要把該物件作為引數傳給fieldX的get()方法。
fieldX.get(p1) 。
getField()方法只能得到類中公有的成員,要得到私有成員,學要用到另一個方法:
getDeclaredField(
)
該方法可以訪問類中的private成員。
得到該成員之後,並不能直接拿來用,要先把該私有成員設定為可以使用,才可以拿來用,通過下面方法把得到的私有成員設定為可以用的:
fieldX.setAccessible(true);
Field類還提供了一個得到所有成員變數的方法:getFields()
通過下面程式演示。
Person類中有幾個不同型別的成員變數,通過getFields()方法可以得到所有公有的成員變數。
通過getDeclaredFields()方法可以得到所有的私有成員變數。
通過上面的方法就可以實現成員變數的反射。
成員方法也是類中的成分,所以也可以進行反射。
成員方法的反射用到Method類;一個Method物件代表一個類中的一個方法。
由位元組碼物件呼叫getMethod()方法得到對應方法的反射物件。
Method
method = 位元組碼物件.getMethod(方法名, 引數型別);
method.invoke(物件名,
給方法傳遞的引數);
物件名如果為空,表示該方法不能被物件呼叫,說明該方法是靜態方法。
在Person類中寫一個show()方法:
public void show(String str)
{
System.out.println(str);
}
得到該show()方法的反射物件,並使用反射物件執行該方法
對接受陣列引數的方法進行反射:
要把一個數組作為一個引數傳遞。main()方法的引數就是陣列型別的,以main()方法的反射為例來看看:
出現異常了!為什麼會這樣?
因為在傳遞陣列作為引數時,陣列被拆開了,沒有被當做一個引數傳遞。所以要強調陣列是一個引數。
每一個數組的父類都是Object陣列。
所以使用下面方法可以把陣列轉換為一個引數。
通過上面的幾個例子就可以看出,反射的概念和用法。
反射就是把一個類中的各種元素對映成一個類。
反射的實現就是由類的位元組碼物件得到類中成員變數或成員方法對應的物件。通過該物件的get()方法得到成員變數,或者通過方法物件的invoke()方法實現成員方法。
---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流!
----------------------