Java基础 反射
一、什么是反射?
? ? ? ? 反射是Java最經(jīng)常用到的基礎(chǔ)知識,但是也是比較難理解的一點。今天就來好好說說他。
????? ?根據(jù)反射的普遍解釋就是:在Java運行時環(huán)境中,對于任意一個類,可以知道這個類有哪些屬性和方法。對于任意一個對象,可以調(diào)用它的任意一個方法。這種動態(tài)獲取類的信息以及動態(tài)調(diào)用對象的方法的功能來自于Java 語言的反射(Reflection)機制
????????簡言之,反射(Reflection)就是在Java運行時,動態(tài)獲取類(class)的信息以及動態(tài)調(diào)用對象(Object)的方法的功能。
????? ?反射的優(yōu)缺點:
????? ? 優(yōu)點就是動態(tài)創(chuàng)建對象和編譯,靈活性高。
????? ? 反射的缺點就是對性能有些影響。(缺點實際上由于現(xiàn)在JVM的性能提高,和在開發(fā)時有一些編輯是可控的可以降低對性能的影響)
二、反射的主要用途
????????? ?spring管理著bean組件,簡單來說省去了龐雜的new來調(diào)取對象。這就是我們最長接觸到的反射機制。原來EJB就是通過new這種方式來調(diào)用對象:
????????? ?而spring運用反射則將原來的這種方式直接配置到一個配置文件中來避免ejb對象的頻繁調(diào)用和解耦。
????????????? ??
????????? ?可以從內(nèi)存角度去理解反射,也可以從我反射的定義去理解它。即當我們平時“引入類的名稱->通過new實例化->取得實例化對象”的過程。使用反射就可以變成“實例化對象->getClass()方法->得到完整的類名稱”這樣的過程。
????????? ? 反射機制主要提供了4個功能:
????????????????? ? 1、在運行時判斷任意一個對象所屬的類
????????????????? ? 2、在運行時構(gòu)造任意一個類的對象
????????????????????3、在運行時判斷任意一個類所具有的成員變量
????????????????? ? 4、在運行時調(diào)用任意一個對象的方法
????????? ? Java反射機制常用到4個類:Class,Construct,Field,Method,
????????? ? 其中Construct,Field,Method是屬于Java.lang.refleact包下,releact包主要就是提供反射的API,Class類則獲取一個要操作的類的對象,該對象屬于java.lang.object包,該對象代表一個正在運行的一個類或接口。下圖是jdk源碼,各類所在的位置:
二、反射的分析
? ? 首先,從內(nèi)存角度分析反射。這里引用個經(jīng)常出現(xiàn)的內(nèi)存資料圖片:
????????
????????由圖可知,運行時JVM的內(nèi)存結(jié)構(gòu)。我們平時用IDE開發(fā)時候的.Java先編譯成.class文件,然后被類加載器加載到JVM中。然后被類加載器加載進jvm的內(nèi)存中,此時類Object加載到方法區(qū)中,創(chuàng)建了Object類的class對象到堆中,注意這個不是new出來的對象,而是類的類型對象,每個類只有一個Class對象,作為方法區(qū)類的數(shù)據(jù)結(jié)構(gòu)的接口。jvm創(chuàng)建對象前,會先檢查類是否加載,尋找類對應(yīng)的Class對象,若加載好,則為你的對象分配內(nèi)存,初始化也就是new 。
反射是什么呢?當我們的程序在運行時,需要動態(tài)的加載一些類這些類可能之前用不到所以不用加載到j(luò)vm,而是在運行時根據(jù)需要才加載,這樣的好處對于服務(wù)器來說不言而喻。 舉個例子我們的項目底層有時是用mysql,有時用oracle,需要動態(tài)地根據(jù)實際情況加載驅(qū)動類,這個時候反射就有用了。 假設(shè) com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection這兩個類我們要用,這時候我們的程序就寫得比較動態(tài)化,通過Class tc = Class.forName("com.java.dbtest.TestConnection"); 通過類的全類名讓jvm在服務(wù)器中找到并加載這個類,而如果是oracle則傳入的參數(shù)就變成另一個了。這時候就可以看到反射的好處了,這個動態(tài)性就體現(xiàn)出java的特性了! 舉多個例子,大家如果接觸過spring,會發(fā)現(xiàn)當你配置各種各樣的bean時,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就會根據(jù)你的需求去動態(tài)加載,你的程序就能健壯地運行。????????第二個,就是從Java源碼,反射的定義這個角度去理解,這里需要用到的方式就不再介紹了,因為網(wǎng)上這個方式很多,下面就列出個小栗子:
內(nèi)存角度的分析這里引用了知乎,作者:老頑童周伯通?的觀點和講解。鏈接:https://www.zhihu.com/question/24304289/answer/147529485
總結(jié)
- 上一篇: Java基础 抽象类和接口的区别、eq
- 下一篇: Java基础 正则表达式 Patter