在可能會出現(xiàn)exception的地方,要使用 try-catch 或者 throws 或者兩者都要。我的判斷依據(jù)是:如果對可能出現(xiàn)的 exception 不想被外部(方法的調(diào)用者)知道,就在方法內(nèi)部 try-catch 掉這個exception;如果希望外部知道,則在catch到之后把exception直接拋出或者拋出自定義的exception。
一、異常的種類
java異常可以分成兩大類:編譯時異常和運行時異常。編譯時異常代表“無法避免的異?!?,如IOException。這類異常往往是由于外部原因造成的,程序本身無法保證他們不發(fā)生,所以這類異常必須捕獲。如果在函數(shù)內(nèi)部無法處理這個異常必須再次拋出(在函數(shù)后面用throws語句),如果什么都不做就出現(xiàn)編譯錯誤。
運行時異常是指“可以避免的異?!?,如 空指針異常,這類異常都是由程序內(nèi)部原因造成的,是可以避免的。對于這類異??梢院雎运麄?,但一旦發(fā)生程序就會異常終止。這類異常對debug非常有幫助,當(dāng)然,如果需要也可以catch。
另外,有些地方即使不會有Exception,但是從商業(yè)邏輯上是錯誤的、非預(yù)期的,也可以拋出用戶異常。例如,用戶輸入非法,銀行賬戶非法透支等等。
二、主要原則
處理異常的一個重要原則,就是要么處理,要么接著拋,決不能吃掉(You either handle it, or throw it. You don’t eat it.)這就是說,當(dāng)你捕獲一個異常之后,必須決定是否立即處理這個異常,或者繼續(xù)拋出這個異常(或者另一個自定義異常),以便由調(diào)用的客戶端捕獲之。當(dāng)客戶端捕獲到以后,又會繼續(xù)進行類似的判斷。
一般來說,GUI端是要處理異常的,比如JSP捕獲到異常之后,需要先是給用戶一個友好的出錯信息,而不要給出系統(tǒng)的出錯信息。系統(tǒng)的出錯信息一方面不太友好,另一方面提供了太多的系統(tǒng)信息,容易被惡意用戶用來攻擊系統(tǒng)。
換句話說,所有的異常最終必須有一個終極的處理者,這就是GUI。至于中間的環(huán)節(jié),比如在服務(wù)器端運行的JavaBean是否要處理捕獲到的異常,還是繼續(xù)拋出所捕獲的異常,需要視具體情況處理。
除非你想把異常處理的責(zé)任交給調(diào)用者,一般不用throws。 比如你要讀入一些文件,如果你想通知調(diào)用者,讓調(diào)用者決定如何處理這個異常,你就把這個異常throws給調(diào)用者;如果你知道應(yīng)該如何處理這個異常,或者你想把異常馬上解決,你可以就地catch她。
這完全取決于你想把異常自己立即處理還是想把處理責(zé)任返回給調(diào)用者。取決于你的程序的結(jié)構(gòu)和要求。
需要注意的有:
1、如果無法處理某個異常,那就不要捕獲它。
2、如果捕獲了一個異常,請不要胡亂處理它。
3、盡量在靠近異常被拋出的地方捕獲異常。
4、在捕獲異常的地方將它記錄到日志中,除非您打算將它重新拋出。
5、按照您的異常處理必須多精細來構(gòu)造您的方法。
6、需要用幾種類型的異常就用幾種,尤其是對于應(yīng)用程序異常。
三、異常嵌套和捕獲適當(dāng)?shù)漠惓?nbsp;
按照Java語言的定義,所謂異常(Exception)指的就是向調(diào)用方法(calling method)表示發(fā)生非正常情況的習(xí)慣方式。下面討論兩種在處理異常時可茲利用的技術(shù):異常嵌套和捕獲適當(dāng)?shù)漠惓!?nbsp;
異常嵌套
你在試圖捕獲異常并打算扔出異常時該采取什么措施呢?同時,你希望原始的異常信息可用嗎?
要回答以上的問題你不妨嘗試一下NestedException類。具體的編程并不難,唯一要做的無非是利用構(gòu)造器并且重載printStackTrace()以便顯示出正確的數(shù)據(jù)。
此外,你還應(yīng)當(dāng)考慮封裝Throwable而非Exception類來創(chuàng)建更具有重用性的組件。之后,你可以創(chuàng)建NestedRuntimeException變量封裝Throwable但無需對其進行聲明。
捕獲適當(dāng)?shù)漠惓?nbsp;
正確地處理異常并不是一項輕松的任務(wù),這是因為異常的處理有時會導(dǎo)致程序出現(xiàn)其他不明行為。不過,以下三條規(guī)則可以幫助你避免錯誤處理異常所可能遭遇的風(fēng)險。
規(guī)則 #1: 總是捕獲扔出異常的類型而不要理睬異常的超類。 為了遵守通常的代碼習(xí)慣,你可以采用Exception類的大寫字母作為變量名,如下所示:
catch(FileNotFoundException fnfe)
以及
catch(SQLException sqle)
規(guī)則 # 2: 決不讓catch塊留空。在很多情況下雖然確實編寫了try/catch塊但在代碼的catch部分卻什么都沒有做。或者,如果采用了日志API(Logging API),那么請編寫代碼把異常寫到日志中。
規(guī)則 # 3: 決不扔出Exception基類的實例。開發(fā)人員應(yīng)當(dāng)總是扔出自己創(chuàng)建的異常類。
扔出異常的API很難處理。在聲明方法扔出java.lang.Exception的情況下,所有的問題都會強加在API用戶的頭上,這樣他們就無法以一種專業(yè)的編程方式來處理異常。通過為扔出API聲明Exception類的子類這一舉措,API開發(fā)人員就可以減輕用戶的負擔(dān)。
以上提到的兩種技術(shù)在處理異常時還可能用得更好、更適當(dāng)。嵌套技術(shù)令異常扔到另一異常的內(nèi)部,而捕獲適當(dāng)?shù)漠惓A畛绦蛘{(diào)試大大簡化。
浙公網(wǎng)安備 33010602011771號