1. 程式人生 > >java核心技術之反射

java核心技術之反射

Class類,使用.class檔案的父類就是Class。 Class 類的例項表示正在執行的 Java 應用程式中的類和介面。
如何獲取Class類檔案的物件呢?
* A:Object類中的getClass()。
* B:通過資料型別的一個靜態的class屬性。
* C:通過Class類的一個靜態方法forName(),引數為類的路徑。開發中最常用
為什麼開發中使用第三種格式呢?
* 因為我們可以通過配置檔案來提供類的路徑或者方法供我們使用。

Class類中的一個方法:
public T newInstance(); //返回該Class建立此 Class 物件所表示的類的一個新例項

通過反射獲取構造方法並使用。
Class.forName(…)得到了某一個類的位元組碼檔案物件。接下來,我們要使用該物件去獲取class檔案中的如 下資訊:

  • 構造方法物件 Constructor
  • 成員變數物件 Field
  • 成員方法物件 Method
  • 這裡寫圖片描述

如果只使用無參構造來生成例項。則使用位元組碼物件直接呼叫newInstance()即可。

Object student = Class.forName("student").newInstance();

內部原理是先獲取無參構造,再用無參構造建立物件。
如果傳遞給Method物件的invoke()方法的第一個引數為null,這有著什麼樣的意義呢?說明該Method物件對應的是一個靜態方法!
這裡寫圖片描述

c.getDeclaredConstructor();//表示獲取所以識別符號的構造方法。c.getConstructor()是獲取public修飾的
然後在呼叫setAccessible(true);表示無論它是什麼型別的識別符號。通通可以操作。(也就是說private的限制失效了)

jdk1.4和jdk1.5的invoke方法的區別:
•Jdk1.5:public Object invoke(Object obj,Object… args)
•Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的語法,需要將一個數組作為引數傳遞給invoke方法時,陣列中的每個元素分別對應被呼叫方法中的一個引數,所以,呼叫charAt方法的程式碼也可以用Jdk1.4改寫為 charAt.invoke(“obj”, new Object[]{wx})形式。
這裡寫圖片描述

反射最常見的用途就是通過Properties配置檔案來建立類的例項,並且訪問該例項的內容。避免了不斷的修改程式碼。
通過反射,可以給有泛型的集合新增泛型之外的元素。因為泛型僅僅是給編譯器看的,而不會對應到位元組碼中。
當使用反射的Class.forName(“Student”);的時候。會執行類Student的靜態程式碼塊

Java建立物件的幾種方式(重要):
(1) 用new語句建立物件,這是最常見的建立物件的方法。
(2) 運用反射手段,呼叫java.lang.Class或者java.lang.reflect.Constructor類的newInstance()例項方法。
(3) 呼叫物件的clone()方法。
(4) 運用反序列化手段,呼叫java.io.ObjectInputStream物件的 readObject()方法。
(1)和(2)都會明確的顯式的呼叫建構函式 ;(3)是在記憶體上對已有物件的影印,所以不會呼叫建構函式 ;(4)是從檔案中還原類的物件,也不會呼叫建構函式。