首頁  >  文章  >  Java  >  帶你搞懂JAVA反射機制(總結分享)

帶你搞懂JAVA反射機制(總結分享)

WBOY
WBOY轉載
2022-03-16 18:02:451728瀏覽

本篇文章為大家帶來了關於java的相關知識,其中主要介紹了反射機制的相關問題,包括了什麼是反射、反射能夠做什麼、反射相關API等等,希望對大家有幫助。

推薦學習:《java學習教學

1、什麼是反射?

在java開發中有一個非常重要的概念就是java反射機制,也是java的重要特徵之一。

反射的概念是由Smith在1982年首次提出的,主要是指程式可以存取、檢測和修改它本身狀態或行為的一種能力,透過反射可以呼叫私有方法和私有屬性,大部分框架也都是運用反射原理的。

Reflection(反射)是被視為動態語言的關鍵,反射機制允許程式在執行期借助於Reflection API取得任何
類別的內部信息,並能直接操作任意物件的內部屬性及方法。

一個類別有多個組成部分,例如:成員變數、方法、建構方法等,反射就是載入類別,並解剖出類別的各個組成部分。

2、反射能夠幹嘛?

Java的反射機制它知道類別的基本結構,這種對Java類別結構探知的能力,我們稱為Java類別的「自審」。如eclipse中,一按點,編譯工具就會自動的把該物件能夠使用的所有的方法和屬性全部都列出來,供使用者進行選擇。這就是利用了Java反射的原理,是對我們創造物件的探知、自審。

反射能夠做到:

  • 在執行階段判斷任意一個物件所屬的類別;
  • 在執行時建構任意一個類別的物件;
  • 在執行階段判斷任意一個類別所具有的成員變數和方法;
  • 在執行時取得泛型資訊;
  • 在執行階段呼叫任意一個物件的成員變數和方法;
  • 在執行是處理註解;
  • 產生動態代理;

3、反射相關API

  • ##java .lang.Class:反射的源頭
  • java.lang.reflect.Method:方法
  • java.lang.reflect.Field:屬性
  • java.lang.reflect.Constructor:建構子
4、Class類別的理解

(1)、介紹:

程式經過javac.exe指令以後,會產生一個或多個字節碼檔案(.class結尾)。接著我們使用java.exe指令對某個字節碼檔進行解釋運行。相當於將某個字節碼檔案載入到記憶體中。此過程就稱為

類別的載入。載入到記憶體中的類,我們就稱為運行時類,此運行時類,就作為Class的實例。

換句話說,Class的實例就對應著一個執行時間類別。

載入到記憶體中的運行時類,會快取一定的時間。在此時間之內,我們可以透過不同的方式

來取得此運行時類別。

(2)、類別的載入程序:

#載入:

在我們new物件或使用

Class.forName("套件名稱.類別")時類別載入器(ClassLoader)會將類別載入到記憶體中,並且建立一個Class物件

如何取得Class物件?

  • 類別.

    class

  • 對象.

    getClass()

  • Class.forName(“套件名稱.類別”);

連結:

連結所做的工作主要是驗證字節碼是否合法,為static 分配記憶體空間並且初始化(並非真正的初始化,只是將對應類型的變數給上預設值,例如int給0,double給0.0)

#卸載:##從記憶體中卸載(不需要我們關心何時卸載,由JVM去做)

(3)類別載入器

類別(CLASS) 只有被載入到JVM 後才能執行。當執行指定程式時,JVM會將編譯產生的.class檔案依照需求和一定的規則載入到記憶體中,組織成為一個完整的Java應用程式。這個載入的過程是由類別載入器來完成的,具體來說,就是由ClassLoader和它的子類別來實現的。類別載入器本身也是一個類,其實質是把類檔案從硬碟讀取到記憶體中!

類別載入器的分類:

  1. BootStrap:主要負責載入核心的類別庫(java.lang.*等),建構ExtClassLoaderAPPClassLoader;
  2. ExtClassLoader:主要負責載入jre/lib/ext目錄下的一些擴充的jar套件;
  3. AppClassLoader:主要負責載入應用程式的主函數類別(自己寫的java檔案是這個類別載入器載入的);
System.out.println("app:" + System.getProperty("java.class.path"));
System.out.println("ext:" + System.getProperty("java.ext.dirs"));
System.out.println("----bootstrap---");
String[] str = System.getProperty("sun.boot.class.path").split(";");

for (String s : str) {
    System.out.println(s);
}

雙親委託(派)機制:

當一個Hello.class這樣的檔案要被載入時。不考慮我們自訂類別載入器,首先會在AppClassLoader中檢查是否載入過,如果有那就無需再載入了。如果沒有,那麼會拿到父載入器,然後呼叫父載入器的loadClass方法。父類中同理也會先檢查自己是否已經加載過,如果沒有再往上走。注意這個類似遞歸的過程,直到到達Bootstrap classLoader之前,都是在檢查是否載入過,並且不會選擇自己去載入。直到BootstrapClassLoader,已經沒有父加載器了,這時候開始考慮自己是否能加載了,如果自己無法加載,會下沉到子加載器去加載,一直到最底層,如果沒有任何加載器能加載,就會拋出ClassNotFoundException。那麼有人就有下面這種疑問了呢?

為什麼要設計這種機制

這種設計有個好處是,如果有人想替換系統層級的類別:String.java。篡改它的實現,在這種機制下這些系統的類別已經被Bootstrap classLoader載入過了(為什麼?因為當一個類別需要載入的時候,最先去嘗試載入的就是BootstrapClassLoader),所以其他類別載入器並沒有機會再去加載,從一定程度上防止了危險代碼的植入。

推薦學習:《java教學

以上是帶你搞懂JAVA反射機制(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除