說說 Java 反射機制

佔小狼發表於2016-09-04

Class物件

虛擬機器在class檔案的載入階段,把類資訊儲存在方法區資料結構中,並在Java堆中生成一個Class物件,作為類資訊的入口。

說說 Java 反射機制

宣告兩個類,Cat.javaDog.java

獲取Class物件一般有三種方式:

  1. 通過例項變數方式
  2. 通過類名方式

    通過這種方式時,只會載入Dog類,並不會觸發其類構造器的初始化。
  3. 通過Class.forName(String classname)方式

    在JDK原始碼實現中,forName方法會呼叫Native方法forName0(),它在JVM中呼叫findClassFromClassLoader()載入Dog類,其原理和ClassLoader一樣,將會觸發Dog類的類構造器初始化,forName0方法宣告如下:

    其中initialize引數,用來告訴虛擬機器是否需要對載入的類進行初始化,如果initialize為false,則不會進行初始化Dog類。

反射機制

反射機制reflect可以在執行期間獲取類的欄位、方法、父類和介面等資訊。
1、獲取類欄位

2、獲取類方法

通過method.invoke(obj, ...args)可以呼叫obj例項的method方法。

3、獲取對應的例項構造器,並生成類例項

如果沒有顯示的宣告預設構造器,class_dog.getConstructor()會丟擲NoSuchMethodException異常。

4、通過newInstance()方法生成類例項

5、設定私有變數

6、獲取私有變數

這種方式在使用Unsafe類進行黑魔法時經常用到。

反射的效能問題

Stackoverflow上,很多人覺得使用反射reflect會影響系統效能,主要有以下幾點看法:
1、程式碼的驗證防禦邏輯過於複雜,本來這塊驗證時在連結階段實現的,使用反射reflect時需要在執行時進行;
2、產生過多的臨時物件,影響GC的消耗;
3、由於缺少上下文,導致不能進行更多的優化,如JIT;

不過現代JVM已經執行的足夠快,我們應該把主要重心放在複雜的程式碼邏輯上,而不是一開始就進行各種效能優化。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

說說 Java 反射機制

相關文章