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


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");
  2. JiaGou jg= (JiaGou)clz.newInstance();

第二種:通過 Constructor 對象的 newInstance() 方法

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

通過 Constructor 對象創建類對象可以選擇特定構造方法,而通過 Class 對象則只能使用默認的無參數構造方法,下面的代碼就調用了一個有參數的構造方法進行了類對象的初始化。

  1. Class clz = Class.forName("com.mikechen.reflection.JiaGou");
  2. Constructor constructor = clz.getConstructor(String.class);
  3. JiaGou jg= (JiaGou)constructor.newInstance("mikechen的互聯網架構");

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

1、獲取類的成員變量的信息

  1. //mikechen的互聯網架構
  2. Field[] fields = cls.getDeclaredFields();

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

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

2、獲得類方法

  1. //mikechen的互聯網架構
  2. Method[] methods = cls.getDeclaredMethods();

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

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

3、獲得構造函數

  1. //mikechen的互聯網架構
  2. 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等等都會用到反射機制。

 

作者:陳睿,英文名 mikechen, 資深技術專家,曾任職阿里、淘寶、百度, 分享十余年BAT架構經驗以及面試心得!
 
關注個人公眾號: mikechen的互聯網架構,第一時間獲取最新BAT架構技術干貨與面試經驗分享!
 
公眾號后台回復 架構,還可以獲取我獨家秘制Java大廠架構干貨視頻噢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM