更新時(shí)間:2020-07-22 15:28:10 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1934次
Javase進(jìn)階視頻教程反射機(jī)制的原理,要想理解反射的原理,首先要了解什么是類型信息。Java讓我們?cè)谶\(yùn)行時(shí)識(shí)別對(duì)象和類的信息,主要有2種方式:一種是傳統(tǒng)的RTTI,它假定我們?cè)诰幾g時(shí)已經(jīng)知道了所有的類型信息;另一種是反射機(jī)制,它允許我們?cè)谶\(yùn)行時(shí)發(fā)現(xiàn)和使用類的信息。
1、Class對(duì)象
理解RTTI在Java中的工作原理,首先需要知道類型信息在運(yùn)行時(shí)是如何表示的,這是由Class對(duì)象來完成的,它包含了與類有關(guān)的信息。Class對(duì)象就是用來創(chuàng)建所有“常規(guī)”對(duì)象的,Java使用Class對(duì)象來執(zhí)行RTTI,即使你正在執(zhí)行的是類似類型轉(zhuǎn)換這樣的操作。
每個(gè)類都會(huì)產(chǎn)生一個(gè)對(duì)應(yīng)的Class對(duì)象,也就是保存在.class文件。所有類都是在對(duì)其第一次使用時(shí),動(dòng)態(tài)加載到JVM的,當(dāng)程序創(chuàng)建一個(gè)對(duì)類的靜態(tài)成員的引用時(shí),就會(huì)加載這個(gè)類。Class對(duì)象僅在需要的時(shí)候才會(huì)加載,static初始化是在類加載時(shí)進(jìn)行的。
public?class?TestMain?{
?public?static?void?main(String[]?args)?{
?System.out.println(XYZ.name);
?}
}
class?XYZ?{
?public?static?String?name?=?"luoxn28";
?static?{
?System.out.println("xyz靜態(tài)塊");
?}
?public?XYZ()?{
?System.out.println("xyz構(gòu)造了");
?}
}
輸出結(jié)果為:
類加載器首先會(huì)檢查這個(gè)類的Class對(duì)象是否已被加載過,如果尚未加載,默認(rèn)的類加載器就會(huì)根據(jù)類名查找對(duì)應(yīng)的.class文件。
想在運(yùn)行時(shí)使用類型信息,必須獲取對(duì)象(比如類Base對(duì)象)的Class對(duì)象的引用,使用功能Class.forName(“Base”)可以實(shí)現(xiàn)該目的,或者使用base.class。注意,有一點(diǎn)很有趣,使用功能”.class”來創(chuàng)建Class對(duì)象的引用時(shí),不會(huì)自動(dòng)初始化該Class對(duì)象,使用forName()會(huì)自動(dòng)初始化該Class對(duì)象。為了使用類而做的準(zhǔn)備工作一般有以下3個(gè)步驟:
加載:由類加載器完成,找到對(duì)應(yīng)的字節(jié)碼,創(chuàng)建一個(gè)Class對(duì)象
鏈接:驗(yàn)證類中的字節(jié)碼,為靜態(tài)域分配空間
初始化:如果該類有超類,則對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊
public?class?Base?{
?static?int?num?=?1;
?
?static?{
?System.out.println("Base?"?+?num);
?}
}
public?class?Main?{
?public?static?void?main(String[]?args)?{
?//?不會(huì)初始化靜態(tài)塊
?Class?clazz1?=?Base.class;
?System.out.println("------");
?//?會(huì)初始化
?Class?clazz2?=?Class.forName("zzz.Base");
?}
}
2、類型轉(zhuǎn)換前先做檢查
編譯器將檢查類型向下轉(zhuǎn)型是否合法,如果不合法將拋出異常。向下轉(zhuǎn)換類型前,可以使用instanceof判斷。
class?Base?{?}
class?Derived?extends?Base?{?}
public?class?Main?{
?public?static?void?main(String[]?args)?{
?Base?base?=?new?Derived();
?if?(base?instanceof?Derived)?{
?//?這里可以向下轉(zhuǎn)換了
?System.out.println("ok");
?}
?else?{
?System.out.println("not?ok");
?}
?}
}
3、反射:運(yùn)行時(shí)類信息
如果不知道某個(gè)對(duì)象的確切類型,RTTI可以告訴你,但是有一個(gè)前提:這個(gè)類型在編譯時(shí)必須已知,這樣才能使用RTTI來識(shí)別它。Class類與java.lang.reflect類庫(kù)一起對(duì)反射進(jìn)行了支持,該類庫(kù)包含F(xiàn)ield、Method和Constructor類,這些類的對(duì)象由JVM在啟動(dòng)時(shí)創(chuàng)建,用以表示未知類里對(duì)應(yīng)的成員。這樣的話就可以使用Contructor創(chuàng)建新的對(duì)象,用get()和set()方法獲取和修改類中與Field對(duì)象關(guān)聯(lián)的字段,用invoke()方法調(diào)用與Method對(duì)象關(guān)聯(lián)的方法。另外,還可以調(diào)用getFields()、getMethods()和getConstructors()等許多便利的方法,以返回表示字段、方法、以及構(gòu)造器對(duì)象的數(shù)組,這樣,對(duì)象信息可以在運(yùn)行時(shí)被完全確定下來,而在編譯時(shí)不需要知道關(guān)于類的任何事情。
反射機(jī)制并沒有什么神奇之處,當(dāng)通過反射與一個(gè)未知類型的對(duì)象打交道時(shí),JVM只是簡(jiǎn)單地檢查這個(gè)對(duì)象,看它屬于哪個(gè)特定的類。因此,那個(gè)類的.class對(duì)于JVM來說必須是可獲取的,要么在本地機(jī)器上,要么從網(wǎng)絡(luò)獲取。所以對(duì)于RTTI和反射之間的真正區(qū)別只在于:
RTTI,編譯器在編譯時(shí)打開和檢查.class文件
反射,運(yùn)行時(shí)打開和檢查.class文件
public?class?Person?implements?Serializable?{
?private?String?name;
?private?int?age;
//?get/set方法
}
public?static?void?main(String[]?args)?{
?Person?person?=?new?Person("luoxn28",?23);
?Class?clazz?=?person.getClass();
?Field[]?fields?=?clazz.getDeclaredFields();
?for?(Field?field?:?fields)?{
?String?key?=?field.getName();
?PropertyDescriptor?descriptor?=?new?PropertyDescriptor(key,?clazz);
?Method?method?=?descriptor.getReadMethod();
?Object?value?=?method.invoke(person);
?System.out.println(key?+?":"?+?value);
?}
}
以上通過getReadMethod()方法調(diào)用類的get函數(shù),可以通過getWriteMethod()方法來調(diào)用類的set方法。通常來說,我們不需要使用反射工具,但是它們?cè)趧?chuàng)建動(dòng)態(tài)代碼會(huì)更有用,反射在Java中用來支持其他特性的,例如對(duì)象的序列化和JavaBean等。
Java視頻教程下載
Javase進(jìn)階教程:http://m.ilovecolors.com.cn/javavideo/144.html
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Javase進(jìn)階視頻教程反射機(jī)制的原理”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)