9:用異常來處理錯(cuò)誤

基本異常
  “異常條件(exceptional condition)”是一種能阻止正在運(yùn)行的方法或其某一部分繼續(xù)運(yùn)行下去的問題。
 
  異常的參數(shù)
    所有的標(biāo)準(zhǔn)異常都有兩個(gè)構(gòu)造函數(shù);第一個(gè)是默認(rèn)的構(gòu)造函數(shù),第二個(gè)是要拿一個(gè)字符串當(dāng)參數(shù)的。

捕獲異常
  “守護(hù)區(qū)域(guarded region)”是一段可能產(chǎn)生異常的代碼,并且后面還跟著要處理這些異常的代碼。
 
  Try區(qū)塊
 
  異常處理程序(exception handler)
 
  “中止”還是“繼續(xù)”

創(chuàng)建你自己的異常
   Thorowable類(Exception是從它那里繼承的)printStackTrace()方法會(huì)返回“被調(diào)用的方法是經(jīng)過怎樣一個(gè)順序到達(dá)異常發(fā)生地點(diǎn)”的信息。缺省情況下,這些信息會(huì)送到標(biāo)準(zhǔn)錯(cuò)誤流,但是這個(gè)方法的重載版也允許你將結(jié)果送到其他流。
   對(duì)于異常類來說,getMessage()有點(diǎn)像toString()。

異常說明
  會(huì)在編譯時(shí)進(jìn)行檢查并且強(qiáng)制得到處理的異常被稱為checked exception.

捕捉任意類型的異常
  重拋異常
    fillInStackTrace(),這個(gè)方法會(huì)將當(dāng)前棧的信息塞進(jìn)舊的異常對(duì)象中,并返回一個(gè)Throwable對(duì)象。
 
  異常鏈(exception chaining)
    JDK 1.4中所有的Throwable的子類都有一個(gè)能接受cause(原因)對(duì)象的構(gòu)造函數(shù)。這個(gè)cause就是用來保存前一個(gè)異常的。
    在Throwable的子類中,只有三種基本的異常類提供了帶cause參數(shù)的構(gòu)造函數(shù),它們是Error(供JVM報(bào)告系統(tǒng)錯(cuò)誤只用), Exception和RuntimeException。如果你要鏈接其他異常,那就不能用構(gòu)造函數(shù),而只能用initCause()方法了。

標(biāo)準(zhǔn)Java異常
  RuntimeException表示編程錯(cuò)誤:
    1。一種你無法預(yù)料的錯(cuò)誤。比如不在你控制之內(nèi)的null reference。
    2。一種由于“程序員忘了檢查它應(yīng)該檢查的錯(cuò)誤條件”而造成的錯(cuò)誤(比如ArrayIndexOutOfBoundsException,你訪問數(shù)組的時(shí)候應(yīng)該對(duì)數(shù)組的大小做一個(gè)檢查)。第一種情況下發(fā)生的異常,經(jīng)常會(huì)演變成第二種情況下的問題。

用finally進(jìn)行清理
  如果你把try區(qū)放進(jìn)一個(gè)循環(huán),你就能構(gòu)建一個(gè)程序運(yùn)行之前必須滿足的條件了。你也可以在循環(huán)里加上static的計(jì)數(shù)器,或其它什么東西,讓它退出之前多試幾種方法。這樣你就能把程序的強(qiáng)壯性就能更上一個(gè)臺(tái)階。
 
  finally是用來干什么的?
    當(dāng)你需要把內(nèi)存以外的東西設(shè)置到原先狀態(tài)的時(shí)候,finally就顯得很有必要了。
    甚至是在“異常沒有被當(dāng)前這組catch子句所捕獲”的情況下,finally也會(huì)在“異常處理機(jī)制在更高一層的運(yùn)行環(huán)境中開始尋找處理程序”之前得到執(zhí)行。
 
  錯(cuò)誤:丟失的異常

加在異常上面的限制
  派生類的構(gòu)造函數(shù)不能捕獲任何由基類構(gòu)造函數(shù)拋出的異常。
  在繼承過程中,編譯器會(huì)對(duì)異常說明作強(qiáng)制要求,但異常說明本身并不屬于方法的特征(signature),特征是由方法的名字與參數(shù)的類型組成的。因此,你不能根據(jù)異常說明來重載方法。此外,一個(gè)出現(xiàn)在基類方法的異常說明中的異常,不一定會(huì)出現(xiàn)在派生類方法的異常說明里。這點(diǎn)同繼承的規(guī)則有明顯不同,在繼承中,基類的方法必須出現(xiàn)在繼承類里。換一句話說,在繼承和覆寫的過程中,方法的“異常說明的接口”不是變大而是變小了--這正好和接口在繼承時(shí)的情形相反。


構(gòu)造函數(shù)
  所有的清理--除了內(nèi)存清理之外--都不會(huì)自動(dòng)發(fā)生。

異常的匹配

其它方法

異常運(yùn)用的原則
  1。在合適的地方處理問題。(避免在自己還不知道該如何處理的情況下去捕捉異常)。
  2。把問題解決掉,然后重新調(diào)用那個(gè)引起問題的方法。
  3。修正一下問題,然后繞過那個(gè)方法再繼續(xù)下去。
  4。用一些別的,不準(zhǔn)備讓這個(gè)方法返回的數(shù)字來進(jìn)行計(jì)算。
  5。把當(dāng)前運(yùn)行環(huán)境下能作的事情全部做完,然后把相同的異常拋到更高層。
  6。把當(dāng)前運(yùn)行環(huán)境下能做的事情全部做完,然后拋一個(gè)不同的異常到更高層。
  7。中止程序。
  8。簡化。(如果異常結(jié)構(gòu)把事情搞得太復(fù)雜了,那用起來回事非常痛苦也很煩人)
  9。把類庫和程序做得更安全。(這即使在為調(diào)試作短期投資,也是在為程序的健壯性作長期投資。)


總結(jié):Java異常處理的目的就是要讓我們能用比現(xiàn)在更少的代碼,以一種更簡單的方式來開發(fā)大型,可靠的程序,并且讓你在開發(fā)過程中能更自信“你的程序里面沒有未經(jīng)處理地錯(cuò)誤”。異常不是特別難學(xué),但是卻能給項(xiàng)目帶來立桿見影的效果。




                                                                                 2005年03月15日 3:31 PM