《Java編程思想》ch12.通過異常處理錯(cuò)誤

通過異常處理錯(cuò)誤

12.1概念

“異炒赴叮”這個(gè)詞有“我對(duì)此感到意外”的意思。問題出現(xiàn)了码荔,你也許不清楚該如何處理,但你的確知道不應(yīng)該置之不理感挥;你要停下來缩搅,看看是不是有別人或在別的地方,能夠處理這個(gè)問題链快。只是在當(dāng)前的環(huán)境中還沒有足夠的信息來解決這個(gè)問題誉己,所以就把這個(gè)問題提交到一個(gè)更高級(jí)別的環(huán)境中眉尸,在這里將作出正確的決定域蜗。
使用異常所帶來的另一個(gè)相當(dāng)明顯的好處是巨双,它往往能夠降低錯(cuò)誤處理代碼的復(fù)雜度。這種方式不僅節(jié)省代碼霉祸,而且把“描述在正常執(zhí)行過程中做什么事”的代碼和“出了問題怎么辦”的代碼相分離筑累。總之丝蹭,與之前的錯(cuò)誤處理方法相比慢宗,異常機(jī)制使代碼的閱讀、編寫和調(diào)試工作更加井井有條奔穿。

12.2基本異常

異常情形是指阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問題镜沽。你所能做的就是拋出異常,即從當(dāng)前環(huán)境跳出贱田,并且把問題提交給上一級(jí)處理缅茉。
拋出異常后,有幾件事會(huì)隨之發(fā)生男摧。首先蔬墩,將使用new在堆上創(chuàng)建異常對(duì)象。然后耗拓,當(dāng)前的執(zhí)行路徑被終止拇颅,并且從當(dāng)前環(huán)境中彈出對(duì)異常對(duì)象的引用。此時(shí)乔询,異常處理機(jī)制接管程序樟插,并開始尋找一個(gè)恰當(dāng)?shù)牡胤絹砝^續(xù)執(zhí)行程序。這個(gè)恰當(dāng)?shù)牡胤骄褪钱惓L幚沓绦蚋绻龋娜蝿?wù)是將程序從錯(cuò)誤狀態(tài)中恢復(fù)岸夯,以使程序能要么換一種方式運(yùn)行,要么繼續(xù)運(yùn)行下去们妥。
能夠拋出任意類型的Throwable對(duì)象猜扮,它是異常類型的根類。

12.3捕獲異常

try{
  //code that might generate exceptions
}catch(Type1 id1){
  //handle exceptions of Type1
}catch(Type2 id2){
  //handle exceptions of Type2
}

12.4創(chuàng)建自定義異常

要自己定義異常類监婶,必須從已有的異常類繼承旅赢,最好是選擇意思相近的異常類繼承。
Throwable類的printStackTrace()方法將打印“從方法調(diào)用處直到異常拋出處”的方法調(diào)用序列惑惶。

12.5異常說明

異常說明使用了附加的關(guān)鍵字throws煮盼,后面接一個(gè)所有潛在異常類型的列表,示例:

void f() throws TooBig, TooSmall, DivZero{//....

12.6捕獲所有異常

可以只寫一個(gè)異常處理程序來捕獲所有類型的異常带污。通過捕獲異常類型的基類Excpetion來實(shí)現(xiàn):

catch(Exception e){//...
}

如果將異常對(duì)象重新拋出僵控,printStackTrace()方法顯示原來異常拋出點(diǎn)的調(diào)用棧信息,而非重新拋出點(diǎn)的信息鱼冀。而fillInStackTrace()可以更新這個(gè)信息报破。
通過initCause()方法可以構(gòu)造異常鏈

12.7Java標(biāo)準(zhǔn)異常

Throwable這個(gè)Java類被用來表示任何可以作為異常被拋出的類悠就。Throwable對(duì)象可分為兩種類型:Error用來表示編譯時(shí)和系統(tǒng)錯(cuò)誤;Exception是可以被拋出的基本類型充易。
其中梗脾,RuntimeException是一個(gè)特例。屬于運(yùn)行時(shí)異常盹靴,它們會(huì)自動(dòng)被Java虛擬機(jī)拋出炸茧,所以不必在異常說明中把它們列出來。被稱為“不受檢查異掣寰玻”梭冠。這種異常屬于錯(cuò)誤,將被自動(dòng)捕獲改备。

12.8使用finally進(jìn)行清理

希望無論try塊中的異常是否拋出妈嘹,finally代碼都會(huì)執(zhí)行。
finally子句用于當(dāng)要把除內(nèi)存之外的資源恢復(fù)到它們的初始狀態(tài)時(shí)绍妨,這種需要清理的資源包括:已經(jīng)打開的文件或網(wǎng)絡(luò)連接润脸,在屏幕上畫的圖形,甚至可以時(shí)外部世界的某個(gè)開關(guān)他去。
另外毙驯,在一個(gè)方法中可以從多個(gè)點(diǎn)返回(return),finally子句可以保證重要的清理仍舊會(huì)執(zhí)行灾测。
Java的異常實(shí)現(xiàn)也有瑕疵爆价,用某些特殊的方式使用finally子句,會(huì)發(fā)生異常丟失的情況:

try{
  try{
  //拋出了異常1
  }finally{
    //拋出了異常2
  }
}catch(Exception e){
//...
}

該代碼只會(huì)捕獲異常2
另一種丟失異常的方式時(shí)從finally子句中返回

public class ExceptionSilencer{
  public static void main(String[] args){
    try{
        throw new RuntimeException();
    }finally{
      return;
    }
  }
}

12.9異常的限制

當(dāng)覆蓋方法的時(shí)候媳搪,只能拋出在基類方法的異常說明里列出的那些異常铭段。
異常限制對(duì)構(gòu)造器不起作用,子類異常構(gòu)造器可以拋出任何異常秦爆,而不必理會(huì)基類構(gòu)造器所拋出的異常序愚。子類構(gòu)造器的異常說明必須包含基類構(gòu)造器的異常說明。
此外等限,一個(gè)出現(xiàn)在基類方法的異常說明中的異常爸吮,不一定會(huì)出現(xiàn)在派生類方法的異常說明里。換句話說望门,在繼承和覆蓋的過程中形娇,某個(gè)特定方法的“異常說明的接口”不是變大了而是變小了——這恰好和類接口在繼承時(shí)的情形相反。

12.10構(gòu)造器

對(duì)于在構(gòu)造階段可能會(huì)拋出異常筹误,并且要求清理的類桐早,最安全的使用方式是使用嵌套的try子句。基本規(guī)則是:在創(chuàng)建需要清理的對(duì)象后哄酝,立即進(jìn)入一個(gè)try-finally子句所灸。

12.11異常匹配

拋出異常的時(shí)候,異常處理系統(tǒng)會(huì)按照代碼的書寫順序找出“最近”的處理程序炫七。找到匹配的處理程序之后,它就認(rèn)為異常將得到處理钾唬,然后就不再繼續(xù)查找万哪。
查找的時(shí)候并不要求拋出的異常痛處理程序所聲明的異常完全匹配。派生類的對(duì)象也可以匹配其基類的處理程序抡秆。

12.12其他可選方式

待完善

12.13異常使用指南

應(yīng)該在下列情況下使用異常:
1奕巍、 在恰當(dāng)?shù)募?jí)別處理問題
2、解決問題并且重新調(diào)用產(chǎn)生異常的方法
3儒士、進(jìn)行少許修補(bǔ)的止,然后繞過異常發(fā)生的地方繼續(xù)執(zhí)行
4、用別的數(shù)據(jù)進(jìn)行計(jì)算着撩,以代替方法預(yù)計(jì)會(huì)返回的值
5诅福、把當(dāng)前運(yùn)行環(huán)境下能做的事情盡量做完,然后把相同的異常重拋到更高層拖叙。
6氓润、把當(dāng)前運(yùn)行環(huán)境下能做的事情盡量做完,然后把不同的異常重拋到更高層薯鳍。
7咖气、終止程序
8、進(jìn)行簡(jiǎn)化
9挖滤、讓類庫和程序更安全

12.14總結(jié)

異常處理的優(yōu)點(diǎn)之一就是它使得你可以在某處集中精力處理你要解決的問題崩溪,而在另一處處理你編寫的這段代碼中產(chǎn)生的錯(cuò)誤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斩松,一起剝皮案震驚了整個(gè)濱河市伶唯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惧盹,老刑警劉巖抵怎,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異岭参,居然都是意外死亡反惕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門演侯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姿染,“玉大人,你說我怎么就攤上這事⌒停” “怎么了狡汉?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)闽颇。 經(jīng)常有香客問我盾戴,道長(zhǎng),這世上最難降的妖魔是什么兵多? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任尖啡,我火速辦了婚禮,結(jié)果婚禮上剩膘,老公的妹妹穿的比我還像新娘衅斩。我一直安慰自己,他們只是感情好怠褐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布畏梆。 她就那樣靜靜地躺著,像睡著了一般奈懒。 火紅的嫁衣襯著肌膚如雪奠涌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天磷杏,我揣著相機(jī)與錄音铣猩,去河邊找鬼。 笑死茴丰,一個(gè)胖子當(dāng)著我的面吹牛达皿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贿肩,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼峦椰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了汰规?” 一聲冷哼從身側(cè)響起汤功,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎溜哮,沒想到半個(gè)月后滔金,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茂嗓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年餐茵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片述吸。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忿族,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情道批,我是刑警寧澤错英,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站隆豹,受9級(jí)特大地震影響椭岩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜璃赡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一判哥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鉴吹,春花似錦、人聲如沸惩琉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞒渠。三九已至良蒸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伍玖,已是汗流浹背嫩痰。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窍箍,地道東北人串纺。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像椰棘,于是被迫代替她去往敵國(guó)和親纺棺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容