Posted on 2005-03-02 15:40
wxb_nudt 閱讀(1320)
評(píng)論(1) 編輯 收藏 所屬分類:
技術(shù)雜談
Java異常的語(yǔ)法應(yīng)該是很簡(jiǎn)單的,一個(gè)try,catch,finally,一個(gè)throws,throw,兩分鐘就可學(xué)完了。我相信許多人和我一樣,對(duì)于異常是這樣處理的:
1.寫程序時(shí)就等編譯器檢查,一旦通不過就加try,catch;
2.自己拋異常常常忘了在方法聲明時(shí)加throws,而且又不明白為什么有的異常需要throws,而有的又不需要;
3.從來不寫自己的異常類;
4.catch到異常不知道怎么辦,通通加一行printStackTrace拉倒;
如果屬于以上這幾種情況的,我覺得有必要和我一起討論一下Java的異常使用方法。
查閱資料可以得知,Java最主要的異常類包括4種:Throwable、Error、Exception和RuntimeException;其中Throwable是所有異常類的父類,它繼承Object類并實(shí)現(xiàn)Serializable接口;Error和Exception都是Throwable的子類;而RuntimeException是Exception的子類。Exception的子類非常多,但是RuntimeException是一個(gè)特殊的子類,需要單獨(dú)討論。
一般當(dāng)程序員在某個(gè)方法中拋出一個(gè)Exception異常(或者其子類)時(shí),需在方法頭部聲明此方法拋出了一個(gè)異常,就是用throws關(guān)鍵字來聲明;但是如果在方法中拋出一個(gè)RuntimeException或者一個(gè)Error時(shí),則不需要聲明此方法拋出了異常,這是為什么呢?
語(yǔ)法上的約束必然有其背后的道理;如果不去弄明白這些道理而是一味的依賴編輯器來幫忙,則事倍功半。事實(shí)上,Java語(yǔ)言的這種語(yǔ)法含義是:Java編譯器要求Java程序必須捕獲或聲明所有非運(yùn)行時(shí)的異常,也就是說,Exception異常是需查異常,必須由程序員對(duì)它嚴(yán)格的負(fù)責(zé),如果在方法中拋出,必須聲明,如果拋出的異常沒有被catch,則會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤,編譯都不能通過。這是強(qiáng)制性的讓程序員遵守Java的異常規(guī)則。這樣規(guī)定的原因是當(dāng)Exception異常出現(xiàn)時(shí),運(yùn)行的程序還有補(bǔ)救的余地,通過異常處理代碼,可以讓程序恢復(fù)運(yùn)行,如果不捕捉這種異常,則白白浪費(fèi)了補(bǔ)救程序的機(jī)會(huì)。而且,這種異常應(yīng)讓程序員可見,所以必須在方法頭部聲明此方法拋出了某種Exception異常。
那么,Error和RuntimeException都是不需查異常,在方法中拋出這兩種異常都不需要聲明,在程序中不catch它們也不會(huì)造成語(yǔ)法錯(cuò)誤。我的理解是,當(dāng)出現(xiàn)這樣的異常時(shí),運(yùn)行的程序已經(jīng)沒有補(bǔ)救的余地了,于是直接拋出異常讓程序結(jié)束是比較合理的安排。如果在程序運(yùn)行時(shí)出現(xiàn)了Error或者RuntimeException,那么程序員也無能為力,所以它們可以對(duì)程序員透明,也不需要特意聲明讓程序員來處理它們。
現(xiàn)在我們知道,try和catch一般對(duì)Exception及其子類使用,throws也是。而對(duì)于Error和RuntimeException則不需要throws,不過還是可以catch的,但是catch到它們一般也就是釋放資源,退出程序而已。
對(duì)于catch到的異常的處理,最經(jīng)常犯的錯(cuò)誤就是丟失異常,catch到舊的異常拋出新的異常,等到程序出錯(cuò)時(shí)就找不到舊異常的信息了。其實(shí)JDK1.4已經(jīng)提供了這個(gè)問題的解決方案,就是用Exception的構(gòu)造函數(shù)形成異常鏈,用舊異常作為參數(shù)構(gòu)造新異常,這樣就可以在出錯(cuò)時(shí)一步步跟蹤到所有出現(xiàn)過的異常了,這兩個(gè)構(gòu)造函數(shù)就是:
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
就想到這么多,以后有了新體會(huì)再續(xù)。