Java 反射
java反射是什麼?怎麼用java反射?爲什麼要用java反射?問到懷疑人生。。。。-----生無可戀-----
這次我們一起來搞java反射,一次搞懂。
反射基礎知識
類的加載概述
當程序要使用某個類時,如果該類還未加載到內存中,則系統會通過加載、連接、初始化三步來實現對這個類進行初始化
- 加載:將class文件讀入內存中,併爲之創建一個Class對象,任何類被使用時系統都會建立一個Class對象。
- 連接:驗證 是否有正確的內部結構,並和其他類協調一致;準備 負責爲類的靜態成員分配內存,並設置默認初始化值;解析 將類的二進制數據中的符號引用替換爲直接引用
- 初始化:就是類的初始化
類加載器的概述
負責將.class文件加載到內存中,併爲之生成對應的Class對象。類加載器分類及作用如下:
- Bootstrap ClassLoader根類加載器:也被稱爲引導類加載器,負責java核心類的加載。比如System,String等,在JDK中JRE的lib目錄下rt.jar文件中
- Extension ClassLoader擴展類加載器:負責JRE的擴展目錄中jar包的加載,在JDK中JRE的lib目錄下ext目錄中
- System ClassLoader系統類加載器:負責在JVM啓動時加載來自java命令的class文件,以及classpath環境變量所指定的jar包和類路徑
反射概述
Java反射機制是在運行狀態中,對於任意一個類都能夠知道這個類的所有屬性和方法;對於任意一個對象都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。要想解剖一個類必須先獲取該類的class文件對象Class,而解剖使用的就是Class類中的方法,所以先要獲取到每一個字節碼文件對應的Class類型的對象,以下有三種獲取Class類對象方式:
- Object類的getClass()方法,判斷兩個對象是否是同一個字節碼文件
- 靜態屬性class,鎖對象
- Class類中靜態方法forName()讀取配置文件
反射的基本使用
one:獲取構造方法
two:獲取成員變量
three:獲取普通方法
從以上Java反射的基本方法中可以看出反射能力的強大性,使它完全無視private的限制隨心所欲操作;正是因爲java反射能力過於強大致使Java界大佬對reflection褒貶不一,而作爲小白的我們更是應該慎重使用反射,同時也因該具有反射的思想,學會合理的使用反射才能進一步提升自我。
反射的使用
one:取消泛型(泛型只在編譯期有效,在運行期會被擦除掉)
問題:ArrayList<Integer>的一個對象,在這個集合中添加一個字符串數據,如何實現呢?
two:通用操作
問題:此方法可將obj對象中名爲propertyName的屬性的值設置爲value
**反射實現動態代理(重點)
動態代理概述
代理:本來應該自己做的事情請別人來做,被請的人就是代理對象。
動態代理:在程序運行過程中產生一個對象,就是通過反射來生成一個代理,用這個代理讓對象功能更加強大。
在Java中java.lang.reflect包下提供一個Proxy類和一個InvocationHandler接口,通過使用這個類和接口就可以生成動態代理對象;JDK提供的代理只能針對接口做代理其步驟如下(而更加強大的代理有cglib)。
(1)Proxy類中的創建動態代理類對象的方法: public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
(2)newProxyInstance方法最終會調用InvocationHandler的方法: public Object invoke(Object proxy, Method method, Object[] args)
(3)最後我們只需要重寫invoke方法,在代理方法前後加上我們想要加入的功能即可
實現如下:
運行結果如下:
以上爲Java反射的基礎內容,請讀者閱讀並操作後查閱更多資料來進一步學習反射的奧義!
謝謝閱讀 ----知飛翀