在Java的思想里面组去,萬(wàn)事萬(wàn)物皆對(duì)象:
其中類(lèi)也是對(duì)象,所有的類(lèi)都是一個(gè)Class對(duì)象势决,可以通過(guò) 類(lèi)名.class 的方式獲取該類(lèi)的Class對(duì)象阻塑,也可以通過(guò)使用Class類(lèi)的一個(gè)靜態(tài)方法forName("全限定類(lèi)名");的方式獲取該類(lèi)的Class對(duì)象,其中forName()方法當(dāng)類(lèi)名不存在的時(shí)候會(huì)拋出一個(gè)ClassNotFoundException異常果复,有趣的一點(diǎn)是,使用 類(lèi)名.class 的方法類(lèi)不會(huì)初始化陈莽,使用forName()方法 類(lèi)會(huì)初始化。Class類(lèi)的一些方法:
1.getName()和getCanonicalName()方法都會(huì)返回一個(gè)全限定類(lèi)名(包含包名)
2.getSimpleName()該方法返回一個(gè)不包含包名的類(lèi)名
3.getInterfaces()返回該類(lèi)實(shí)現(xiàn)的所有的接口
4.isInterface()該類(lèi)為接口時(shí)返回true,否則返回false走搁;
5.getSuperclass();返回該類(lèi)的直接父類(lèi)的Class對(duì)象
6.newInstance();該方法能夠在沒(méi)有任何類(lèi)型信息的情況下創(chuàng)建一個(gè)該類(lèi)的實(shí)例独柑,并返回一個(gè)Object對(duì)象,當(dāng)然私植,在你可以發(fā)送Object能夠接受的消息之外的任何消息之前忌栅,你更多的了解它并執(zhí)行某種轉(zhuǎn)型,該方法是實(shí)現(xiàn)虛擬構(gòu)造器的一種途徑曲稼,虛擬構(gòu)造器允許你申明:“我不知道你的具體類(lèi)型索绪,但是無(wú)論如何你要正確的創(chuàng)建自己”。示例如下:
interface Run{}
interface Eat{}
interface Sleep{}
class People{
public int a = 10;
People(){}
People(int i){}
@Override
public String toString() {
return "this is a class People toString!";
}
}
class Man extends People implements Run,Eat,Sleep{
Man(){
super(1);
}
}
public class ClassTest {
public static void main(String[] args){
Class c = Class.forName("com.cuit.typeinfo.Man");
Class up = c.getSuperclass();
People people = null;
try {
people = (People) up.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(people.a);
Object obj = null;
try {
obj = up.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(obj.toString());
}
}
在上例中我們并沒(méi)有up的任何更進(jìn)一步的類(lèi)型信息躯肌,只知道他是一個(gè)Class引用者春,但我們利用newInstance()方法成功的獲得了該類(lèi)的實(shí)例,并在知道了他是People類(lèi)的時(shí)候?qū)⑵滢D(zhuǎn)型為People對(duì)象清女。
類(lèi)字面常量:
為了使用類(lèi)而做的準(zhǔn)備工作實(shí)際包含三個(gè)步驟:
1.加載:由類(lèi)加載器執(zhí)行,創(chuàng)建一個(gè)Class對(duì)象
2.鏈接:為靜態(tài)域分配存儲(chǔ)空間晰筛,如果必須將解析這個(gè)類(lèi)創(chuàng)建的對(duì)其他類(lèi)的所有引用
3.初始化:如果該類(lèi)具有超類(lèi)嫡丙,則對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊
關(guān)于初始化有以下幾點(diǎn):
1.初始化被延遲到了對(duì)靜態(tài)方法(構(gòu)造器隱式的是靜態(tài)的)或者非常數(shù)靜態(tài)域進(jìn)行首次引用時(shí)才執(zhí)行
2.關(guān)于 static 和 final 關(guān)鍵字:如果一個(gè)值是編譯期 常量并被聲明為static final那么這個(gè)值不需要初始化便能讀取读第,如果一個(gè)static域不是final的曙博,那么對(duì)它訪(fǎng)問(wèn)時(shí)必須要先進(jìn)行連接(為這個(gè)域分配存儲(chǔ)空間)和初始化(初始化該存儲(chǔ)空間)
泛型與Class:
當(dāng)將泛型語(yǔ)法用于Class對(duì)象時(shí),會(huì)發(fā)生一件有趣的事情:newInstance()方法會(huì)返回該對(duì)象的確切類(lèi)型而不是基本的Object怜瞒,但如果你手頭是超類(lèi)父泳,則有一些不同,如下:
//Class<? super Man> 方式獲得的Class對(duì)象在調(diào)用newInstance()方法時(shí)返回的是Object而不是Man的超類(lèi)People
Class<People> c = People.class;
Class<? super Man> upp = c.getSuperclass();
try {
Object o = upp.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//當(dāng)手頭的是People的子類(lèi)Man時(shí)吴汪,使用newInstance()方法返回People
Class<? extends People> tClass = Man.class;
try {
People people1 = tClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
類(lèi)型轉(zhuǎn)換:
當(dāng)嘗試向上轉(zhuǎn)型時(shí)惠窄,編譯器允許自由的做向上轉(zhuǎn)型的賦值操作,二不需要做任何顯示的轉(zhuǎn)型操作
向下轉(zhuǎn)型:
向下轉(zhuǎn)型時(shí)漾橙,編譯器將檢查向下轉(zhuǎn)型是否合理杆融,因?yàn)樗辉试S向下轉(zhuǎn)型到實(shí)際上不是待轉(zhuǎn)型類(lèi)的子類(lèi)的類(lèi)型上,可以使用關(guān)鍵字instanceof霜运,它返回一個(gè)布爾值脾歇,告訴我們對(duì)象是否是某個(gè)特定類(lèi)的實(shí)例
if(x instanceof Man){
//do something...
}
動(dòng)態(tài)的instanceof: isInstance(T);