Java API中這么解釋Class類:
為了理解RTTI在Java例如何工作,首先必須了解類型信息在運(yùn)行期間是如何表示的。只要用到一個(gè)名為'Class'的特殊形式的對(duì)象,這個(gè)對(duì)象包含了與類有關(guān)的信息(有時(shí)候也把它叫作“元類”)。事實(shí)上,要用Class類創(chuàng)建屬于某個(gè)類的全部“常規(guī)”或“普通”對(duì)象。 任何一個(gè)作為程序一部分的類,都有一個(gè)Class對(duì)象。換言之,每次寫一個(gè)新類時(shí),同時(shí)也會(huì)創(chuàng)建一個(gè)Class對(duì)象(更恰當(dāng)?shù)恼f,是保存在一個(gè)完全同名的.class文件中)。在運(yùn)行期間,一旦程序員想要生成某一個(gè)類的對(duì)象,用于執(zhí)行程序的Java虛擬機(jī)(JVM)首先就會(huì)檢查該類型的Class對(duì)象是否已經(jīng)載入。若尚未載入,JVM就會(huì)查找同名的.class文件,并將其載入。所以,Java程序啟動(dòng)時(shí)并不是完全載入的,這一點(diǎn)與許多傳統(tǒng)語言不同。一旦該類型的Class對(duì)象進(jìn)入內(nèi)存,就用它創(chuàng)建該類型的所有對(duì)象。 三、Class動(dòng)態(tài)加載類的三種方法 (1)類名.Class (2)類型.getClass() (3)Class.forName('類名') (這里的類名表示具體類名,所以要加上包名) 補(bǔ)充: 靜態(tài)加載類和動(dòng)態(tài)加載類: 編譯時(shí)刻加載的類是靜態(tài)加載類,例如用new關(guān)鍵字創(chuàng)建的對(duì)象要通過編譯器的靜態(tài)檢查,如果編譯時(shí)該類不存在,那么使用該對(duì)象的類也無法通過編譯。 運(yùn)行時(shí)刻加載的類是動(dòng)態(tài)類,在編譯的時(shí)候不會(huì)進(jìn)行判斷,只有在運(yùn)行時(shí)才會(huì)進(jìn)行判斷,假設(shè)該類不存在,在運(yùn)行時(shí)才會(huì)報(bào)錯(cuò)。 例如下面的例子: Candy.java文件 package com.test;
public class Candy {
static{
System.out.println('Loading Candy in static block');
}
public static void main(String[] args){
System.out.println('Loading Candy in main method');
}
}
LoadClass.java文件: 運(yùn)行結(jié)果如下:
Before loding Candy 從程序的輸出結(jié)果來看,用這種方式和new 來創(chuàng)建對(duì)象沒什么區(qū)別。其實(shí),二者之間有很大的區(qū)別,用new 關(guān)鍵字創(chuàng)建對(duì)象要通過編譯器靜態(tài)檢查,如果編譯時(shí)Candy類不存在,那么使用Candy類對(duì)象的類LoadClass也無法通過編譯。而forName()方法時(shí)動(dòng)態(tài)加載,即便編譯時(shí)Candy類不存在,編譯也是可以通過的,只是在運(yùn)行時(shí)刻會(huì)拋出異常。 注意:使用forName()方法存在一個(gè)問題,它返回的是一個(gè)Class類型,而不是加載的那個(gè)類型。所以,無法做出下面的聲明: Candy candy=Class.forName('com.test.Candy'); 也就是說,candy無法直接使用Candy類中定義的方法。解決的辦法是利用反射機(jī)制,不過這比直接用new來創(chuàng)建對(duì)象要麻煩得多。所以,用forName()加載對(duì)象多用在加載驅(qū)動(dòng)程序的情況下(例如,加載數(shù)據(jù)庫驅(qū)動(dòng))
下面舉個(gè)例子熟悉一下Class動(dòng)態(tài)加載類的方法: package com.baseType;
public class baseClass {
public static void main(String[] args){
Class c1=int.class; //int的類類型
Class c2=String.class; //String類的類類型
Class c3=double.class; //double的類類型
Class c4=Double.class; //Double類的類類型
Class c5=void.class; //關(guān)鍵字void的類類型
//打印類類型的具體名稱
System.out.println(c1.getName()); //int
System.out.println(c2.getName()); //java.lang.String
System.out.println(c3.getName()); //double
System.out.println(c4.getName()); //java.lang.Double
System.out.println(c5.getName()); //void
//不帶包名的類名稱
System.out.println(c2.getSimpleName()); //String
System.out.println(c4.getSimpleName()); //Double
}
} |
|