Java反射機制詳解
什么是反射?
反射是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為 Java 語言的反射機制。
哪里用到反射機制
JDBC中,利用反射動態(tài)加載了數(shù)據(jù)庫驅(qū)動程序。
Web服務(wù)器中利用反射調(diào)用了Sevlet的服務(wù)方法。
Eclispe等開發(fā)工具利用反射動態(tài)刨析對象的類型與結(jié)構(gòu),動態(tài)提示對象的屬性和方法。
很多框架都用到反射機制,注入屬性,調(diào)用方法,如Spring。
動態(tài)代理是什么
有哪些應(yīng)用?
動態(tài)代理是運行時動態(tài)生成代理類。
動態(tài)代理的應(yīng)用有 Spring AOP數(shù)據(jù)查詢、測試框架的后端 mock、rpc,Java注解對象獲取等。
怎么實現(xiàn)動態(tài)代理
JDK 原生動態(tài)代理和 cglib 動態(tài)代理。
JDK 原生動態(tài)代理是基于接口實現(xiàn)的,而 cglib 是基于繼承當前類的子類實現(xiàn)的。
Java反射機制的作用
在運行時判斷任意一個對象所屬的類
在運行時構(gòu)造任意一個類的對象
在運行時判斷任意一個類所具有的成員變量和方法
在運行時調(diào)用任意一個對象的方法
Java 反射機制的優(yōu)缺點
優(yōu)點:
- 能夠運行時動態(tài)獲取類的實例,大大提高系統(tǒng)的靈活性和擴展性。
- 與 Java 動態(tài)編譯相結(jié)合,可以實現(xiàn)無比強大的功能。
- 對于 Java 這種先編譯再運行的語言,能夠讓我們很方便的創(chuàng)建靈活的代碼,這些代碼可以在運行時裝配,無需在組件之間進行源代碼的鏈接,更加容易實現(xiàn)面向?qū)ο蟆?/li>
缺點:
- 反射會消耗一定的系統(tǒng)資源,因此,如果不需要動態(tài)地創(chuàng)建一個對象,那么就不需要用反射;
- 反射調(diào)用方法時可以忽略權(quán)限檢查,獲取這個類的私有方法和屬性,因此可能會破壞類的封裝性而導(dǎo)致安全問題。
如何使用Java的反射
通過一個全限類名創(chuàng)建一個對象
Class.forName(“全限類名”);
例如:com.mysql.jdbc.Driver Driver類已經(jīng)被加載到 jvm中,并且完成了類的初始化工作就行了
類名.class; 獲取Class<?> clz 對象
對象.getClass();
獲取構(gòu)造器對象,通過構(gòu)造器new出一個對象
Clazz.getConstructor([String.class]);
Con.newInstance([參數(shù)]);
通過class對象創(chuàng)建一個實例對象(就相當與new類名()無參構(gòu)造器)
Cls.newInstance();
通過class對象獲得一個屬性對象
Field c=cls.getFields():獲得某個類的所有的公共(public)的字段,包括父類中的字段。
Field c=cls.getDeclaredFields():獲得某個類的所有聲明的字段,即包括public、private和proteced,但是不包括父類的聲明字段
通過class對象獲得一個方法對象
Cls.getMethod(“方法名”,class……parameaType);(只能獲取公共的)
Cls.getDeclareMethod(“方法名”);(獲取任意修飾的方法,不能執(zhí)行私有)
M.setAccessible(true);(讓私有的方法可以執(zhí)行)
讓方法執(zhí)行
Method.invoke(obj實例對象,obj可變參數(shù));
-----(是有返回值的)
//測試類 public class Demo { public String name; public void inputAndoutput { BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(System.out)); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String aa; while ( !(aa= br.readLine()).equals("bye")){ bufferedWriter.write(aa); bufferedWriter.newLine(); bufferedWriter.flush(); } br.close(); bufferedWriter.close(); } public Demo(){ } public void print(){ System.out.println(this.name); } public void reverseWords(String s) { System.out.println(s); return s; } }
//利用反射 Class c=new Demo().getClass(); System.out.println(c.toString()); Class[] classes=c.getClasses(); for (Class ca:classes){ System.out.println(ca.toString()); } Arrays.stream(c.getFields()).forEach(s->{ System.out.println(s.toString()); });
到此這篇關(guān)于Java反射機制詳解的文章就介紹到這了,更多相關(guān)Java反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea創(chuàng)建項目沒有webapp文件夾的解決方法
本文主要介紹了idea創(chuàng)建項目沒有webapp文件夾的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05mybatis中 if-test 數(shù)字判斷的坑及解決
這篇文章主要介紹了mybatis中 if-test 數(shù)字判斷的坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06淺談@RequestParam(required = true)的誤區(qū)
這篇文章主要介紹了@RequestParam(required = true)的誤區(qū),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11java基礎(chǔ)知識之FileInputStream流的使用
這篇文章主要介紹了java基礎(chǔ)知識之FileInputStream流的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12Java數(shù)據(jù)結(jié)構(gòu)之查找
本文主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中查找的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03