java反射是Java被視為動態(或準動態)語言的一個關鍵性質,Java反射機制容許程序在運行時加載、探知、使用編譯期間完全未知的classes。換言之,Java可以加載一個運行時才得知名稱的class,獲得其完整結構。
在工作過程中,常會聽到反射這個概念,在平常的代碼開發中也有看到和使用到,只是對它沒有一個較深入的了解,這次重新理解學習了一下反射機制,結合公司產品中的Hotweb框架,加深理解,本文為學習過程中的總結。
靜態加載類(編譯時加載類):大多數情況下都是使用這種形式。比如我們定義了一個類A,實例化采用A a = new A()接著就可以通過a對象調用相關方法或屬性,這就是靜態加載類的過程。
動態加載類(運行時加載類):所謂動態加載類,只需要通過Class c = Class.forName("類的全名")即可獲得類類型,然后通過調用A a = c.newInstance()方法即可實例化這個類。
本質的區別在于靜態加載的類的源程序在編譯時期加載(必須存在),而動態加載的類在編譯時期可以缺席(源程序不必存在)。
反射機制:在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
反射機制主要提供了以下功能:
在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。在JDK中,主要通過以下類實現java反射機制,這些類都位于java.lang.reflect包中。
Class:代表一個類Filed:代表類的成員變量或者說成員屬性Method:代表類的方法Constructor:代表類的構造方法Array:提供了動態創建數組,以及訪問數組元素的靜態方法首先,需要定義測試使用的類


Class 類的實例,表示正在運行的 Java 應用程序中的類和接口。獲取類的Class對象有多種方式:

可以通過反射機制得到某個類的某個屬性,然后改變對應于這個類的某個實例的該屬性值。JAVA 的Class<T>類提供了幾個方法獲取類的屬性。

使用樣例如下圖所示:

可見getFields和getDeclaredFields區別:
getFields返回的是申明為public的屬性,包括父類中定義,
getDeclaredFields返回的是指定類定義的所有定義的屬性,不包括父類的。
通過反射機制得到某個類的某個方法,然后調用對應于這個類的某個實例的該方法
Class<T>類提供了幾個方法獲取類的方法。

使用樣例如下圖所示:

通過反射機制得到某個類的構造器,然后調用該構造器創建該類的一個實例
Class<T>類提供了幾個方法獲取類的構造器。
 使用樣例如下圖所示:
使用樣例如下圖所示:

通過反射機制創建新類的實例,有幾種方法可以創建

通過反射獲取類Method對象,調用Field的Invoke方法調用函數。

調用后結果如下圖所示

上面失敗是由于沒有權限調用PRivate函數,這里需要設置accessible為true;
 
通過反射獲取類的Field對象,調用Field方法設置或獲取值

調用后結果如下圖:

Person中有兩個方法,sayHi和sayHello

通過已定義的類字符串變量,實例化該類,創建對象,然后根據傳入的方法參數,調用Person中的方法

調用后結果如下圖:

不管是類名還是方法名,都可以定義在配置文件中,然后讀取實例化、方法調用,通常Java web框架都是如此,數通暢聯Hotweb MVC框架也有類似機制,具體參加5.4節。
在泛型為Integer的ArrayList中存放一個String類型的對象。

修改數組的信息實例,如下圖:

修改數組的大小實例,如下圖:

以數通暢聯基礎Hotweb MVC框架為例說明反射機制
首先,在DispatchServlet轉發請求至Handler時,需要實例化handler對象。

其中,在HandlerParser類中,使用handlerId通過配置文件HandlerModule.xml讀取到對應Handler并實例化。

然后,通過instantiateHandler方法,添加handler的屬性,

最后,在實例化了handler對象后,通過傳入名為actionType的變量參數調用handler中對應名稱的方法。

在獲取方法名的時候,默認是prepareDisplay


最后,通過反射得到的Method對象,調用Field的Invoke方法調用指定的函數。

新聞熱點
疑難解答