您好,登錄后才能下訂單哦!
Java中反射機制的原理?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
1. 簡單,只需理解基本的概念,就可以編寫適合于各種情況的應用程序;2. 面向?qū)ο螅?. 分布性,Java是面向網(wǎng)絡的語言;4. 魯棒性,java提供自動垃圾收集來進行內(nèi)存管理,防止程序員在管理內(nèi)存時容易產(chǎn)生的錯誤。;5. 安全性,用于網(wǎng)絡、分布環(huán)境下的Java必須防止病毒的入侵。6. 體系結(jié)構(gòu)中立,只要安裝了Java運行時系統(tǒng),就可在任意處理器上運行。7. 可移植性,Java可以方便地移植到網(wǎng)絡上的不同機器。8.解釋執(zhí)行,Java解釋器直接對Java字節(jié)碼進行解釋執(zhí)行。
Java 反射機制
Reflection(反射)是被視為動態(tài)語言的關(guān)鍵,反射機制允許程序在執(zhí)行期借助于Reflection
API取得任何類的內(nèi)部信息,并能直接操作任意對象的內(nèi)部屬性及方法。
Java反射機制提供的功能
在運行時判斷任意一個對象所屬的類
在運行時構(gòu)造任意一個類的對象
在運行時判斷任意一個類所具有的成員變量和方法
在運行時調(diào)用任意一個對象的成員變量和方法
生成動態(tài)代理
反射相關(guān)的主要API:
java.lang.Class:代表一個類
java.lang.reflect.Method:代表類的方法
java.lang.reflect.Field:代表類的成員變量
java.lang.reflect.Constructor:代表類的構(gòu)造方法
Class類
對照鏡子后可以得到的信息:某個類的屬性、方法和構(gòu)造器、某個類到底實現(xiàn)了哪些接口。對于每個類而言,JRE 都為其保留一個不變的 Class類型的對象。一個 Class對象包含了特定某個類的有關(guān)信息。
Class本身也是一個類
Class對象只能由系統(tǒng)建立對象
一個類在JVM 中只會有一個Class實例
一個Class對象對應的是一個加載到JVM中的一個.class文件
每個類的實例都會記得自己是由哪個Class 實例所生成
通過Class可以完整地得到一個類中的完整結(jié)構(gòu)
實例化Class類對象
1、前提:若已知具體的類,通過類的class屬性獲取,該方法最為安全可靠,程序性能最高
實例:
Class clazz = String.class;
2、前提:已知某個類的實例,調(diào)用該實例的getClass()方法獲取Class對象
實例:
Class clazz ="www.atguigu.com".getClass();
3、前提:已知一個類的全類名,且該類在類路徑下,可通過Class類的靜態(tài)方法forName()獲取,可能拋出
ClassNotFoundException
實例:
Classclazz= Class.forName("java.lang.String");
4、其他方式(不做要求)
ClassLoader cl =this.getClass().getClassLoader(); Classclazz4 = cl.loadClass("類的全類名");
創(chuàng)建類對象并獲取類的完整結(jié)構(gòu)
1.創(chuàng)建類的對象:調(diào)用Class對象的newInstance()
方法
要求:
1)類必須有一個無參數(shù)的構(gòu)造器。
2)類的構(gòu)造器的訪問權(quán)限需要足夠。
難道沒有無參的構(gòu)造器就不能創(chuàng)建對象了嗎?
不是!只要在操作的時候明確的調(diào)用類中的構(gòu)造方法,并將參數(shù)傳遞進去之后,才可以實例化操作。步驟如下:
1)通過Class類的getDeclaredConstructor(Class …parameterTypes)取得本類的指定形參類型的構(gòu)造器
2)向構(gòu)造器的形參中傳遞一個對象數(shù)組進去,里面包含了構(gòu)造器中所需的各個參數(shù)。
//1.根據(jù)全類名獲取對應的Class對象 String name = "atguigu.java.Person"; Class clazz = null; clazz = Class.forName(name); //2.調(diào)用指定參數(shù)結(jié)構(gòu)的構(gòu)造器,生成Constructor的實例 Constructor con = clazz.getConstructor(String.class,Integer.class); //3.通過Constructor的實例創(chuàng)建對應類的對象,并初始化類屬性 Person p2 = (Person) con.newInstance("Peter",20); System.out.println(p2);
通過反射調(diào)用類的完整結(jié)構(gòu)
使用反射可以取得:
1.實現(xiàn)的全部接口
public Class
通過反射調(diào)用類中的指定方法、指定屬性
1.調(diào)用指定方法
通過反射,調(diào)用類中的方法,通過Method類完成。步驟:
1.通過Class類的getMethod(String name,Class…parameterTypes)
方法取得一個Method對象,并設置此方法操作時所需要的參數(shù)類型。
2.之后使用Object invoke(Object obj, Object[] args)
進行調(diào)用,并向方法中傳遞要設置的obj對象的參數(shù)信息。
Object invoke(Object obj, Object … args)
說明:
1.Object 對應原方法的返回值,若原方法無返回值,此時返回null
2.若原方法若為靜態(tài)方法,此時形參Objectobj可為null
3.若原方法形參列表為空,則Object[]args為null
4.若原方法聲明為private,則需要在調(diào)用此invoke()方法前,顯式調(diào)用方法對象的 setAccessible(true)方法,將可訪問private的方法。
2.調(diào)用指定屬性
在反射機制中,可以直接通過Field類操作類中的屬性,通過Field類提供的set()和get()方法就可以完成設置和取得屬性內(nèi)容的操作。
public Field getField(Stringname)
返回此Class對象表示的類或接口的指定的public的Field。 public Field getDeclaredField(Stringname)
返回此Class對象表示的類或接口的指定的Field。
在Field中:
public Object get(Object obj)
取得指定對象obj上此Field的屬性內(nèi)容 public void set(Object obj,Objectvalue)
設置指定對象obj上此Field的屬性內(nèi)容
注:在類中屬性都設置為private的前提下,在使用set()和get()方法時,首先要使用Field類中的setAccessible(true)方法將需要操作的屬性設置為可以被外部訪問。 public void setAccessible(true)
訪問私有屬性時,讓這個屬性可見。
Java動態(tài)代理
1、動態(tài)代理是指客戶通過代理類來調(diào)用其它對象的方法,并且是在程序運行時根據(jù)需要動態(tài)創(chuàng)建目標類的代理對象。
2、動態(tài)代理使用場合:
調(diào)試
遠程方法調(diào)用
3、代理設計模式的原理:
使用一個代理將對象包裝起來, 然后用該代理對象取代原始對象. 任何對原始對象的調(diào)用都要通過代理. 代理對象決定是否以及何時將方法調(diào)用轉(zhuǎn)到原始對象上
4、Proxy :專門完成代理的操作類,是所有動態(tài)代理類的父類。通過此類為一個或多個接口動態(tài)地生成實現(xiàn)類。
5、提供用于創(chuàng)建動態(tài)代理類和動態(tài)代理對象的靜態(tài)方法
static Class
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。