標籤:bool 產生 函數 cep 繼承 body 聲明 getx col
一、反射(Reflection)
1、反射的概念
反射是程式可以訪問、檢測和修改它本身狀態或者行為的能力。通過反射,可以動態擷取對象資訊以及動態調用對象的方法。
反射的基礎是因為在運行狀態中,JVM能夠知道對象的所有屬性和方法,並且能夠調用它的任意一個方法或訪問其任一屬性。
反射機制使得程式可以在運行時動態載入、查看和使用編譯期間完全未知的類(對象)。
2、反射機制提供的功能
- 運行時檢測對象的類型;
- 動態建立對象;
- 減速對象的屬性和方法;
- 調用對象的任意方法;
- 修改構造器、方法和屬性的可見度;
- 動態組建代理程式。
3、反射的通常用途
- 用於程式檢查工具和調試器,它能擷取程式在運行時刻的內部結構;
- 在運行時刻與註解配合,動態改變對象的行為,例如,為特定對象添加日誌、許可權控制等操作。
二、反射的實現
1、反射機制的實現基於4個類,也可以把他們看成一個類的各個部分。
Class:代表運行時對象的類型資訊,JVM使用這些類型資訊確定方法。
Constructor:表示類的構造器,即構造方法的描述類。
Field:用來描述對象的屬性集合。
Method:用來描述方法。
值得注意的是,通過上面方法訪問反射機制建立的對象的私人構造器、屬性、方法(少見)時,要先通過setAccessible(boolean T_or_F)方法修改存取權限!
2、Class類——反射的基石
Class類的對象用來描述運行時的類和介面,也用來表達enum、數組、基礎資料型別 (Elementary Data Type)以及關鍵詞void。當一個類被載入或者當類載入器的defineClass()方法被調用,JVM就會自動產生一個Class對象。
要查看任何類,都必須獲得一個Class對象。然後由Class對象調用反射APIs。
怎麼獲得Class對象?兩種方式:
public class role{}/*第一種*/Class cls=Role.class;/*第二種,forName()方法的參數必須是完整的路徑類名(包名+類名),並且該方法需要捕獲ClassNotFoundException異常。*/Class cls=Class.forName(“cn.edu.ldu.javacourse.ch7.Role”);
在得到Class的執行個體對象後就可以建立Role類的執行個體了,newInstance()調用類的預設構造器產生對象:
/*newInstance()方法的缺點是只能調用預設建構函式*/Object o=cls.newInstance();
Class的其他方法可以擷取到類的構造方法、屬性和成員方法:
- getConstructor();
- getField();
- getMethod();
同時這三個方法還有相應的getDeclaredxxx()版本,只擷取該類自己聲明的成員而不是從父類繼承。
3、Constructor類——擷取構造器
Constructor類是構造方法的描述類,Constructors對象可以通過Class對象的4個getXXX()方法獲得(也可以獲得構造器數組):
/*Class類有4個方法獲得Constructors對象*/ Constructors con=cls.getXXXX();/*然後設定所獲得的構造器的存取權限*/con. setAccessible(true);/*通過con的newInstance()方法建立新的對象*/Object obj=con.newInstance (new Object[]{“Jerry”});/*若要使用私人構造器,記得修改存取權限*/
4、Field類——擷取成員變數
成員變數用Field類進行封裝,使用與上面相似。
/*返回了方法名*/Field mem=cls.getDeclaredField("fieldName");mem.setAccessible(true);System.out.println("we get fields:"+mem.get(obj));/*訪問私人變數也要改變存取權限*/
5、Method類——擷取方法
Method類封裝方法,基於反射擷取並執行方法:
Method me=cls.getMethod("methodBame",null);Object name=me.invoke(obj,null);
6、數組
數組與所有對象一樣,都通過Class的對象描述,也可使用標準getClass()方法獲得數組的Class對象。
但是數組不是類,沒有建構函式也沒有可訪問的屬性和方法。即反射為普通類提供的訪問函數不能用於數組。
反射處理數組使用java.lang.reflect.Array類提供的靜態方法,可以建立新的數組,可以獲得數組對象的長度,以及讀、寫數組對象的索引值。
反射機制建立數組:
/*第一個參數int.class指定數群組類型,第二個參數聲明數組中元素的個數。*/int[] intArray=(int[]) Array.newInstance( int.class, 3);/*訪問通過反射建立的數組*//*intArray參數是一個具體的數組*/Array.get (intArray,0);Array.set (intArray,index,value);
思考,怎麼重新調整現有數組大小?
Java 反射機制