Java進(jìn)階教程之運(yùn)行時(shí)類型識(shí)別RTTI機(jī)制
運(yùn)行時(shí)類型識(shí)別(RTTI, Run-Time Type Identification)是Java中非常有用的機(jī)制,在Java運(yùn)行時(shí),RTTI維護(hù)類的相關(guān)信息。
多態(tài)(polymorphism)是基于RTTI實(shí)現(xiàn)的。RTTI的功能主要是由Class類實(shí)現(xiàn)的。
Class類
Class類是"類的類"(class of classes)。如果說(shuō)類是對(duì)象的抽象和集合的話,那么Class類就是對(duì)類的抽象和集合。
每一個(gè)Class類的對(duì)象代表一個(gè)其他的類。比如下面的程序中,Class類的對(duì)象c1代表了Human類,c2代表了Woman類。
public class Test
{
public static void main(String[] args)
{
Human aPerson = new Human();
Class c1 = aPerson.getClass();
System.out.println(c1.getName());
Human anotherPerson = new Woman();
Class c2 = anotherPerson.getClass();
System.out.println(c2.getName());
}
}
class Human
{
/**
* accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
private int height;
}
class Woman extends Human
{
/**
* new method
*/
public Human giveBirth()
{
System.out.println("Give birth");
return (new Human());
}
}
當(dāng)我們調(diào)用對(duì)象的getClass()方法時(shí),就得到對(duì)應(yīng)Class對(duì)象的引用。
在c2中,即使我們將Women對(duì)象的引用向上轉(zhuǎn)換為Human對(duì)象的引用,對(duì)象所指向的Class類對(duì)象依然是Woman。
Java中每個(gè)對(duì)象都有相應(yīng)的Class類對(duì)象,因此,我們隨時(shí)能通過(guò)Class對(duì)象知道某個(gè)對(duì)象“真正”所屬的類。無(wú)論我們對(duì)引用進(jìn)行怎樣的類型轉(zhuǎn)換,對(duì)象本身所對(duì)應(yīng)的Class對(duì)象都是同一個(gè)。當(dāng)我們通過(guò)某個(gè)引用調(diào)用方法時(shí),Java總能找到正確的Class類中所定義的方法,并執(zhí)行該Class類中的代碼。由于Class對(duì)象的存在,Java不會(huì)因?yàn)轭愋偷南蛏限D(zhuǎn)換而迷失。這就是多態(tài)的原理。

getClass: 我是誰(shuí)?
除了getClass()方法外,我們還有其他方式調(diào)用Class類的對(duì)象。
public class Test
{
public static void main(String[] args)
{
Class c3 = Class.forName("Human");
System.out.println(c1.getName());
Class c4 = Woman.class
System.out.println(c2.getName());
}
}
上面顯示了兩種方式:
1.forName()方法接收一個(gè)字符串作為參數(shù),該字符串是類的名字。這將返回相應(yīng)的Class類對(duì)象。
2.Woman.class方法是直接調(diào)用類的class成員。這將返回相應(yīng)的Class類對(duì)象。
Class類的方法
Class對(duì)象記錄了相應(yīng)類的信息,比如類的名字,類所在的包等等。我們可以調(diào)用相應(yīng)的方法,比如:
getName() 返回類的名字
getPackage() 返回類所在的包
可以利用Class對(duì)象的newInstance()方法來(lái)創(chuàng)建相應(yīng)類的對(duì)象,比如:
Human newPerson = c1.newInstance();
newInstance()調(diào)用默認(rèn)的不含參數(shù)的構(gòu)建方法。
我們可以獲得類定義的成員:
getFields() 返回所有的public數(shù)據(jù)成員
getMethods() 返回所有的public方法
可以進(jìn)一步使用Reflection分析類。這里不再深入。
Class類更多的方法可查詢官方文檔:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html
Class類的加載
當(dāng)Java創(chuàng)建某個(gè)類的對(duì)象,比如Human類對(duì)象時(shí),Java會(huì)檢查內(nèi)存中是否有相應(yīng)的Class對(duì)象。
如果內(nèi)存中沒(méi)有相應(yīng)的Class對(duì)象,那么Java會(huì)在.class文件中尋找Human類的定義,并加載Human類的Class對(duì)象。
在Class對(duì)象加載成功后,其他Human對(duì)象的創(chuàng)建和相關(guān)操作都將參照該Class對(duì)象。
相關(guān)文章
ShardingSphere如何進(jìn)行sql重寫(xiě)示例詳解
這篇文章主要為大家介紹了ShardingSphere如何進(jìn)行sql重寫(xiě)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
Java實(shí)現(xiàn)斷點(diǎn)下載服務(wù)端與客戶端的示例代碼
這篇文章主要為大家介紹了如何實(shí)現(xiàn)服務(wù)端(Spring Boot)與客戶端(Android)的斷點(diǎn)下載與下載續(xù)傳功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08
Spring事件監(jiān)聽(tīng)機(jī)制ApplicationEvent方式
這篇文章主要介紹了Spring事件監(jiān)聽(tīng)機(jī)制ApplicationEvent方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
SpringBoot Shiro 權(quán)限注解不起作用的解決方法
本文主要介紹了SpringBoot Shiro 權(quán)限注解不起作用的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
解決Eclipse中java文件的圖標(biāo)變成空心J的問(wèn)題
這篇文章主要介紹了解決Eclipse中java文件的圖標(biāo)變成空心J的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Springboot集成swagger實(shí)現(xiàn)方式
這篇文章主要介紹了Springboot集成swagger實(shí)現(xiàn)方式,通過(guò)簡(jiǎn)單的示例代碼詳細(xì)描述了實(shí)現(xiàn)過(guò)程步驟,有需要的朋友可以借鑒參考下,希望可以有所幫助2021-08-08
Java實(shí)現(xiàn)任意進(jìn)制轉(zhuǎn)換
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)任意進(jìn)制轉(zhuǎn)換的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Java編程關(guān)于子類重寫(xiě)父類方法問(wèn)題的理解
這篇文章主要介紹了Java編程關(guān)于子類重寫(xiě)父類方法問(wèn)題的理解,分享了有關(guān)子類重寫(xiě)父類的實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11

