當(dāng)一個(gè)空的引用去訪問(wèn)實(shí)例變量會(huì)出現(xiàn)什么問(wèn)題嗎?請(qǐng)看以下代碼:
public class Balloon {
//顏色
String color;
//氣體
String gas;
//構(gòu)造方法
public Balloon(){
}
public Balloon(String _color , String _gas){
color = _color;
gas = _gas;
}
}
public class BalloonTest {
public static void main(String[] args) {
Balloon ball = new Balloon("紅色" , "氫氣");
System.out.println("氣球顏色是:" + ball.color);
System.out.println("氣球中的氣體是:" + ball.gas);
ball = null;
//空指針異常
System.out.println("氣球顏色是:" + ball.color);
}
}
運(yùn)行結(jié)果如下圖所示:
圖9-22:空指針異常演示
java.lang.NullPointerException被稱(chēng)為空指針異常,在java編程當(dāng)中屬于很常見(jiàn)的異常,接下來(lái)研究一下以上程序執(zhí)行過(guò)程的內(nèi)存圖是如何變化的。請(qǐng)看下圖:
圖9-23:Balloon ball = new Balloon("紅色" , "氫氣");
圖9-24:ball = null;
以上程序語(yǔ)法正確,編譯通過(guò),因?yàn)槌绦蛟诰幾g階段檢測(cè)出“引用ball”屬于Balloon類(lèi)型,在Balloon類(lèi)中有color屬性,所以編譯器允許通過(guò)ball引用去訪問(wèn)color屬性,例如以上代碼的ball.color。但是程序在運(yùn)行階段會(huì)通過(guò)ball引用查找堆內(nèi)存當(dāng)中的對(duì)象,因?yàn)閏olor是實(shí)例變量,該變量存儲(chǔ)在java對(duì)象內(nèi)部,當(dāng)ball = null執(zhí)行之后表示“引用ball”不再保存java對(duì)象的內(nèi)存地址,換句話說(shuō)通過(guò)ball引用已經(jīng)無(wú)法找到堆內(nèi)存當(dāng)中的java對(duì)象了,對(duì)于程序來(lái)說(shuō)這個(gè)時(shí)候就沒(méi)有辦法正常訪問(wèn)了,這種情況下就會(huì)發(fā)生空指針異常。就好比一個(gè)小孩兒放風(fēng)箏,通過(guò)拽線來(lái)操控風(fēng)箏,結(jié)果線斷了,再拽風(fēng)箏線的時(shí)候,已經(jīng)無(wú)法再操控風(fēng)箏了,這對(duì)于小孩兒來(lái)說(shuō)是一種異常。而java程序中把這種異常叫做NullPointerException。
總之,當(dāng)一個(gè)“空的引用”去訪問(wèn)“對(duì)象相關(guān)/實(shí)例相關(guān)”數(shù)據(jù)的時(shí)候,此時(shí)一定會(huì)發(fā)生空指針異常。