Java反射詳解:入門+使用+原理+應用場景

mikechen的網際網路架構發表於2022-01-14

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

反射非常強大和有用, 現在市面上絕大部分框架(spring、mybatis、rocketmq等等)中都有反射的影子,反射機制在框架設計中佔有舉足輕重的作用。

所以,在你Java進階的道路上,你需要掌握好反射。

怎麼才能學好反射,我們需要弄懂以下幾個問題:

1.反射是什麼?

2.反射有什麼用?

3.反射的實現原理?

4.怎麼用反射?

下面我就針對以上的疑問,一一來講解。

反射是什麼?

反射是java語言的一個特性,它允程式在執行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。

反射是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法,對於任意一個物件,都能夠呼叫它的任意方法和屬性,這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。

一句話總結:反射就是在執行時才知道要操作的類是什麼,並且可以在執行時獲取類的完整構造,並呼叫對應的方法。

為什麼要用反射?

Java Reflection功能非常強大,並且非常有用,比如:

  • 獲取任意類的名稱、package資訊、所有屬性、方法、註解、型別、類載入器等
  • 獲取任意物件的屬性,並且能改變物件的屬性
  • 呼叫任意物件的方法
  • 判斷任意一個物件所屬的類
  • 例項化任意一個類的物件
  • 透過反射我們可以實現動態裝配,降低程式碼的耦合度,動態代理等。

怎麼使用反射?

一般情況下我們透過反射建立類物件主要有兩種方式:

  • 透過 Class 物件的 newInstance() 方法
  • 透過 Constructor 物件的 newInstance() 方法

第一種:透過 Class 物件的 newInstance() 方法。

  1. Class clz = Class.forName("com.mikechen.reflection.JiaGou");JiaGou jg= (JiaGou)clz.newInstance();

第二種:透過 Constructor 物件的 newInstance() 方法

Class clz = Class.forName("com.mikechen.reflection.JiaGou");
Constructor constructor = clz.getConstructor();
JiaGou jg= (JiaGou)constructor.newInstance();

透過 Constructor 物件建立類物件可以選擇特定構造方法,而透過 Class 物件則只能使用預設的無引數構造方法,下面的程式碼就呼叫了一個有引數的構造方法進行了類物件的初始化。

Class clz = Class.forName("com.mikechen.reflection.JiaGou");
Constructor constructor = clz.getConstructor(String.class);
JiaGou jg= (JiaGou)constructor.newInstance("mikechen的網際網路架構");

接下來我們就可以透過具體的API呼叫獲取到詳細的屬性或者方法等詳細了。

1、獲取類的成員變數的資訊

//mikechen的網際網路架構Field[] fields = cls.getDeclaredFields();

更加詳細成員變數獲取參考如下:

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

2、獲得類方法

//mikechen的網際網路架構Method[] methods = cls.getDeclaredMethods();

更加詳細方法獲取參考如下:

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

3、獲得建構函式

//mikechen的網際網路架構Constructor[] constructors = cls.getDeclaredConstructors();

更加詳細建構函式獲取參考如下:

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

這樣透過反射就可以做在執行時獲取類的完整構造,並獲得類資訊了。

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

透過以上一個小案例瞭解了反射的使用,但如果你想對反射掌握得更好,還需深入理解反射背後的底層實現原理。

反射工作原理?

呼叫反射的總體流程如下:

1、當我們編寫完一個Java專案之後,每個java檔案都會被編譯成一個.class檔案。

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

2、這些class檔案在程式執行時會被ClassLoader載入到JVM中,當一個類被載入以後,JVM就會在記憶體中自動產生一個Class物件。

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

3、透過Class物件獲取Field/Method/Construcor

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

我們一般平時是透過new的形式建立物件實際上就是透過這些Class來建立的,只不過這個class檔案是編譯的時候就生成的,程式相當於寫死了給jvm去跑。

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

反射是什麼呢?當我們的程式在執行時,需要動態的載入一些類這些類可能之前用不到所以不用載入到jvm,而是在執行時根據需要才載入。

原來使用new的時候,需要明確的指定類名,這個時候屬於硬編碼實現,而在使用反射的時候,可以只傳入類名引數,就可以生成物件,降低了耦合性,使得程式更具靈活性。

反射的應用場景

Java反射詳解:入門+使用+原理+應用場景-mikechen的網際網路架構

舉個例子我們的專案底層資料庫有時是用mysql,有時用oracle,需要動態地根據實際情況載入驅動類,這個時候反射就有用了,假設 com.mikechen.java.myqlConnection,com.mikechen.java.oracleConnection這兩個類我們要用。

這時候我們在使用 JDBC 連線資料庫時使用 Class.forName()透過反射載入資料庫的驅動程式,如果是mysql則傳入mysql的驅動類,而如果是oracle則傳入的引數就變成另一個了。

Spring 框架的 IOC(動態載入管理 Bean),Spring透過配置檔案配置各種各樣的bean,你需要用到哪些bean就配哪些,spring容器就會根據你的需求去動態載入,你的程式就能健壯地執行。

還有Spring AOP(動態代理)功能都和反射有關係。

除此之外還有很多框架:mybatis、dubbo、rocketmq等等都會用到反射機制。

--END--

關於作者 :陳睿,英文名   資深技術專家,曾任職阿里、淘寶、百度, 分享十餘年BAT架構經驗以及面試心得!
關注個人公眾號: mikechen的網際網路架構,第一時間獲取最新BAT架構技術乾貨與面試經驗分享!
Java反射詳解:入門+使用+原理+應用場景

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011997/viewspace-2852263/,如需轉載,請註明出處,否則將追究法律責任。

相關文章