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

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

推薦學習:《》

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);
}

雙親委託(派)機制:

img

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

為什麼要設計這種機制

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

推薦學習:《》

以上就是帶你搞懂JAVA反射機制(總結分享)的詳細內容,更多請關注TW511.COM其它相關文章!