Java反射的使用和原理詳解
1. 反射是什么?
反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查并且對內(nèi)部的成員進行操作。
反射是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法,對于任意一個對象,都能夠調(diào)用它的任意方法和屬性,這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射機制。
一句話總結:反射就是在運行時才知道要操作的類是什么,并且可以在運行時獲取類的完整構造,并調(diào)用對應的方法。
2. 為什么要用反射?
Java Reflection功能非常強大,并且非常有用,比如:
- 獲取任意類的名稱、package信息、所有屬性、方法、注解、類型、類加載器等
- 獲取任意對象的屬性,并且能改變對象的屬性
- 調(diào)用任意對象的方法
- 判斷任意一個對象所屬的類
- 實例化任意一個類的對象
- 通過反射我們可以實現(xiàn)動態(tài)裝配,降低代碼的耦合度,動態(tài)代理等。
3. 怎么使用反射?
一般情況下我們通過反射創(chuàng)建類對象主要有兩種方式:
- 通過 Class 對象的 newInstance() 方法
- 通過 Constructor 對象的 newInstance() 方法
第一種:通過 Class 對象的 newInstance() 方法。
- 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 對象創(chuàng)建類對象可以選擇特定構造方法,而通過 Class 對象則只能使用默認的無參數(shù)構造方法,下面的代碼就調(diào)用了一個有參數(shù)的構造方法進行了類對象的初始化。
- Class clz = Class.forName("com.mikechen.reflection.JiaGou");
- Constructor constructor = clz.getConstructor(String.class);
- JiaGou jg= (JiaGou)constructor.newInstance("mikechen的互聯(lián)網(wǎng)架構");
接下來我們就可以通過具體的API調(diào)用獲取到詳細的屬性或者方法等詳細了。
3.1 獲取類的成員變量的信息
Field[] fields = cls.getDeclaredFields();
3.2 獲得類方法
Method[] methods = cls.getDeclaredMethods();
3.3 獲得構造函數(shù)
Constructor[] constructors = cls.getDeclaredConstructors();
這樣通過反射就可以做在運行時獲取類的完整構造,并獲得類信息了。
4. 反射工作原理
調(diào)用反射的總體流程如下:
1、當我們編寫完一個Java項目之后,每個java文件都會被編譯成一個.class文件。
2、這些class文件在程序運行時會被ClassLoader加載到JVM中,當一個類被加載以后,JVM就會在內(nèi)存中自動產(chǎn)生一個Class對象。
3、通過Class對象獲取Field/Method/Construcor
我們一般平時是通過new的形式創(chuàng)建對象實際上就是通過這些Class來創(chuàng)建的,只不過這個class文件是編譯的時候就生成的,程序相當于寫死了給jvm去跑。
反射是什么呢?當我們的程序在運行時,需要動態(tài)的加載一些類,這些類可能之前用不到所以不用加載到jvm,而是在運行時根據(jù)需要才加載。
原來使用new的時候,需要明確的指定類名,這個時候?qū)儆谟簿幋a實現(xiàn),而在使用反射的時候,可以只傳入類名參數(shù),就可以生成對象,降低了耦合性,使得程序更具靈活性。
5. 反射的應用場景
舉個例子我們的項目底層數(shù)據(jù)庫有時是用mysql,有時用oracle,需要動態(tài)地根據(jù)實際情況加載驅(qū)動類,這個時候反射就有用了,假設 com.mikechen.java.myqlConnection,com.mikechen.java.oracleConnection這兩個類我們要用。
這時候我們在使用 JDBC 連接數(shù)據(jù)庫時使用 Class.forName()通過反射加載數(shù)據(jù)庫的驅(qū)動程序,如果是mysql則傳入mysql的驅(qū)動類,而如果是oracle則傳入的參數(shù)就變成另一個了。
Spring 框架的 IOC(動態(tài)加載管理 Bean),Spring通過配置文件配置各種各樣的bean,你需要用到哪些bean就配哪些,spring容器就會根據(jù)你的需求去動態(tài)加載,你的程序就能健壯地運行。
還有Spring AOP(動態(tài)代理)功能都和反射有關系。
除此之外還有很多框架:mybatis、dubbo、rocketmq等等都會用到反射機制。
到此這篇關于Java反射的使用和原理詳解的文章就介紹到這了,更多相關Java反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java報錯:java.lang.UnsatisfiedLinkError問題的解決辦法
在Java開發(fā)中,java.lang.UnsatisfiedLinkError是一種與本地方法調(diào)用相關的常見異常,本文將詳細分析這一異常的背景、可能的原因、錯誤代碼示例、正確代碼示例,以及編寫代碼時需要注意的事項,需要的朋友可以參考下2024-09-09springboot整合curator實現(xiàn)分布式鎖過程
這篇文章主要介紹了springboot整合curator實現(xiàn)分布式鎖過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05Springboot使用jxls實現(xiàn)同sheet多個列表展示
這篇文章主要介紹了Springboot使用jxls實現(xiàn)同sheet多個列表展示,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08基于Comparator對象集合實現(xiàn)多個條件按照優(yōu)先級的比較
這篇文章主要介紹了基于Comparator對象集合實現(xiàn)多個條件按照優(yōu)先級的比較,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07