黑馬程序員——反射

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity開發</a>、<a href="http://www.itheima.com"target="blank">.Net培訓</a>、期待與您交流! ----------------------

 

反射  

反射技術:其實就是動態加載一個指定的類,並獲取該類中的所有的內容。而且將字節

碼文件封裝成對象,並將字節碼文件中的內容都封裝成對象,這樣便於操作這些成員。

簡單說:反射技術可以對一個類進行解剖。 反射的好處:大大的增強了程序的擴展性。

 反射的基本步驟: 

1、獲得Class對象,就是獲取到指定的名稱的字節碼文件對象。

2、 2、實例化對象,獲得類的屬性、方法或構造函數。

3、 3、訪問屬性、調用方法、調用構造函數創建對象。

 獲取這個Class對象,有三種方式: 

1:通過每個對象都具備的方法getClass來獲取。弊端:必須要創建該類對象,纔可以調用getClass方法。 

2:每一個數據類型(基本數據類型和引用數據類型)都有一個靜態的屬性class。弊端:必須要先明確該類。 

 前兩種方式不利於程序的擴展,因爲都需要在程序使用具體的類來完成。 

3:使用的Class類中的方法,靜態的forName方法。 

 指定什麼類名,就獲取什麼類字節碼文件對象,這種方式的擴展性最強,只要將類名的字符串傳入即可。 

// 1. 根據給定的類名來獲得  用於類加載 

String classname = "cn.itcast.reflect.Person";// 來自配置文件

 Class clazz = Class.forName(classname);// 此對象代表Person.class

 // 2. 如果拿到了對象,不知道是什麼類型   用於獲得對象的類型 

Object obj = new Person(); 

Class clazz1 = obj.getClass();// 獲得對象具體的類型 

// 3. 如果是明確地獲得某個類的Class對象  主要用於傳參

 Class clazz2 = Person.class; 

反射的用法: 

1)、需要獲得java類的各個組成部分,首先需要獲得類的Class對象,獲得Class對象的三種方式: 

Class.forName(classname) 用於做類加載 

obj.getClass() 用於獲得對象的類型 

類名.class     用於獲得指定的類型,傳參用 

2)、反射類的成員方法: 

Class clazz = Person.class; 

Method method = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2}); 

method.invoke(); 

3)、反射類的構造函數: 

Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...}) con.newInstance(params...)

4)、反射類的屬性: 

Field field = clazz.getField(fieldName); 

field.setAccessible(true);

 field.setObject(value); 

獲取了字節碼文件對象後,最終都需要創建指定類的對象: 

創建對象的兩種方式(其實就是對象在進行實例化時的初始化方式) 

1,調用空參數的構造函數:使用了Class類中的newInstance()方法。 

2,調用帶參數的構造函數:先要獲取指定參數列表的構造函數對象,然後通過該構造函數的對象的newInstance(實際參數進行對象的初始化。 

綜上所述,第二種方式,必須要先明確具體的構造函數的參數類型,不便於擴展。

所以一般情況下,被反射的類,內部通常都會提供一個公有的空參數的構造函數。

 ------------------------------------------------------

 // 如何生成獲取到字節碼文件對象的實例對象。 

Class clazz = Class.forName("cn.itcast.bean.Person");//類加載 

// 直接獲得指定的類型 

clazz = Person.class; 

// 根據對象獲得類型 

Object obj = new Person("zhangsan", 19); 

clazz = obj.getClass(); 

Object obj = clazz.new Instance();//該實例化對象的方法調用就是指定類中的空參數構造函數,給創建對象進行初始化。當指定類中沒有空參數構造函數時,該如何創建該類對象呢?請看method_2(); 

public static void method_2() throws Exception { 

Class clazz = Class.forName("cn.itcast.bean.Person"); 

//既然類中沒有空參數的構造函數,那麼只有獲取指定參數的構造函數,用該函數來進行實例化。 

//獲取一個帶參數的構造器。 

Constructor constructor = clazz.getConstructor(String.class,int.class);

 //想要對對象進行初始化,使用構造器的方法newInstance(); 

Object obj = constructor.newInstance("zhagnsan",30);

 //獲取所有構造器。 

Constructor[] constructors = clazz.getConstructors();//只包含公共的 

constructors = clazz.getDeclaredConstructors();//包含私有的 

for(Constructor con : constructors) { System.out.println(con); 

  反射指定類中的方法: 

//獲取類中所有的方法。 

public static void method_1() throws Exception { 

Class clazz = Class.forName("cn.itcast.bean.Person"); 

Method[] methods = clazz.getMethods();//獲取的是該類中的公有方法和父類中的公有方法。 

methods = clazz.getDeclaredMethods();//獲取本類中的方法,包含私有方法。

 for(Method method : methods) { System.out.println(method); 

//獲取指定方法; 

public static void method_2() throws Exception { 

Class clazz = Class.forName("cn.itcast.bean.Person"); 

//獲取指定名稱的方法。 

Method method = clazz.getMethod("show", int.class,String.class); 

//想要運行指定方法,當然是方法對象最清楚,爲了讓方法運行,調用方法對象的invoke方法即可,但是方法運行必須要明確所屬的對象和具體的實際參數。 

Object obj = clazz.newInstance(); 

method.invoke(obj, 39,"hehehe");//執行一個方法 } 

//想要運行私有方法。 

public static void method_3() throws Exception { 

Class clazz = Class.forName("cn.itcast.bean.Person");

 //想要獲取私有方法。必須用getDeclearMethod(); 

Method method = clazz.getDeclaredMethod("method", null); 

// 私有方法不能直接訪問,因爲權限不夠。非要訪問,可以通過暴力的方式。 

method.setAccessible(true);//一般很少用,因爲私有就是隱藏起來,所以儘量不要訪問。 } 

//反射靜態方法。 

public static void method_4() throws Exception { 

Class clazz = Class.forName("cn.itcast.bean.Person"); 

Method method = clazz.getMethod("function",null);

 method.invoke(null,null); 

 

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity開發</a>、<a href="http://www.itheima.com"target="blank">.Net培訓</a>、期待與您交流! ----------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章