Java 异常处理学习总结
????? Java 異常處理學(xué)習(xí)總結(jié) ---------------------------------------------------------------------------------------
?
????? 1.? 語(yǔ)言提供內(nèi)建一致的錯(cuò)誤處理機(jī)制,避免不一致的錯(cuò)誤處理方式和風(fēng)格。其基本思想是,讓錯(cuò)誤源將合適的信息傳到某個(gè)接收者進(jìn)行處理;這個(gè)接收者可能與錯(cuò)誤源位于同一抽象層次,更可能位于更高的抽象層次。做個(gè)簡(jiǎn)單的類比,當(dāng)員工無(wú)法處理某些問(wèn)題時(shí),就要提交到高層管理去處理。
?
????? 2. ? Java 的異常處理語(yǔ)法并不多, try-catch-finally, throw, throws ,關(guān)鍵在于異常的合理使用: 何時(shí)使用異常;如何正確使用異常;當(dāng)異常發(fā)生時(shí),要確保程序處于正確穩(wěn)定的狀態(tài)下。You should always ask : when exception happens , will everything properly cleanup ?
?
???? 3.?? 異常處理機(jī)制的益處: 將正確情形代碼與錯(cuò)誤處理相分離。
???? 遵循傳統(tǒng)錯(cuò)誤處理方式的代碼是:???????????????????????????????????? 使用異常處理的代碼是:
???? if1 (! Exception1) {???????????????????????????????????????????????????????????????????????? try?? {
????????????? // 正確情形代碼1??????????????????????????????????????????????????????????????????????????????????? // 正確情形代碼1 ……
???? }???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? // 正確情形代碼N
???? else1 {????????????????????????????????????????????????????????????????????????????????????????????? } catch (Exception1) {
???????????? //? 錯(cuò)誤情形代碼1????????????????????????????????????????????????????????????????????????????????? //? 錯(cuò)誤情形代碼1
???? }???????????????????????????????????????????????????????????????????????????????????????????????????????? }
???? ……????????????????????????????????????????????????????????????????????????????????????????????????? ……
?
???? ifN (! ExceptionN) {???????????????????????????????????????????????????????????????????????? } catch (ExceptionN) {
????????????? // 正確情形代碼N???????????????????????????????????????????????????????????????????????????????? // 錯(cuò)誤情形代碼N
???? }????????????????????????????????????????????????????????????????????????????????????????????????????????? } finally {
???? elseN {????????????????????????????????????????????????????????????????????????????????????????????????????????? // 清理資源,或使程序回復(fù)某個(gè)狀態(tài)
???????????? //? 錯(cuò)誤情形代碼N??????????????????????????????????????????????????????????????????? }
???? }
?
???? 4.? 自定義異常的方法很簡(jiǎn)單,讓它繼承自Java 中的已有異常,比如 Exception . 自定義異常的一個(gè)重要事項(xiàng)是異常類的名字必須取好,望文生義,具有自描述性。因?yàn)?#xff0c;錯(cuò)誤源的信息提示是非常重要的。
?
???? 5.? 異常的重要繼承體系: RuntimeException ---> Exception --- > Throwable , Error ---> Throwable . 其它異常均是繼承于此。異常的重要方法有: getClass().getName() [獲取異常類名];getMessage() , getLocalizedMessage() [異常信息]; new SomeException(String), new SomeException(Throwable)[構(gòu)造器]; fillInStackTrace(), getCause() [用于重拋異常];initCause(Throwable) [異常鏈] ;printStackTrace() , printStackTrace(PrintStream) , printStackTrace(PrintWriter) [打印異常發(fā)生棧調(diào)用信息] 。
?
???? 6.? Java 異常鏈: 將剛剛捕獲的異常對(duì)象作為構(gòu)造器參數(shù)傳入將要拋出的異常對(duì)象,或者作為 initCause() 方法的參數(shù)傳入,可以使即將拋出的異常保存有剛剛捕獲的異常對(duì)象的信息,構(gòu)成異常鏈,用來(lái)表達(dá)因果關(guān)系。
?
???? 7.? 若類的方法 f 中拋出異常A1,A2,...,An,則該方法的聲明必須指定異常聲明 f() throws A1, A2, ..., An (A1, A2, ..., An 若是 RuntimeException 或其派生類異常,則可以不指定。)
?
???? 8.?? 異常占位或預(yù)留技術(shù): 方法中并不拋出異常,但方法中仍然指定該異常聲明 。這樣做的好處時(shí),當(dāng)真正需要在方法中拋出該異常時(shí),不會(huì)影響客戶代碼;因?yàn)榭蛻舸a已經(jīng)對(duì)該異常進(jìn)行處理了(在沒(méi)有實(shí)際拋出該異常之前)。
?
???? 9.?? 異常聲明限制:
????? (1) 子類構(gòu)造器的異常聲明列表必須是基類構(gòu)造器異常聲明列表的超集,即:若基類構(gòu)造器的異常聲明列表是 {A1,A2,...,An} , 則子類構(gòu)造器的異常聲明列表 S >= {A1,A2,...An} ; 這是因?yàn)?#xff0c;調(diào)用子類構(gòu)造器之前必然調(diào)用基類構(gòu)造器,因此,子類構(gòu)造器必須處理基類構(gòu)造器所聲明的所有異常;
???? (2) 子類覆寫(xiě)方法的異常聲明列表必須是基類方法異常聲明列表的子集,即:若基類方法的異常聲明列表是 {A1,A2,...,An} , 則子類覆寫(xiě)方法的異常聲明列表 S <= {A1,A2,...An} ; 這是因?yàn)?#xff0c; 客戶代碼是基于基類方法提供的公共接口來(lái)編程的,只應(yīng)當(dāng)處理基類方法提供的公共接口所聲明的異常。
???? (3) 子類型的接口實(shí)現(xiàn)方法的異常聲明列表必須是接口方法異常聲明列表的子集。這是因?yàn)?#xff0c;客戶代碼是基于接口方法的聲明來(lái)編程的,只應(yīng)當(dāng)處理接口方法提供的異常說(shuō)明。
?
???? 10. ? RuntimeException 及其派生類的特殊性:?
???? (1) 若異常發(fā)生,則系統(tǒng)會(huì)自動(dòng)拋出RuntimeException 或其派生類對(duì)象,無(wú)需程序員顯式拋出;
???? (2) 若方法中拋出 RuntimeException 或其派生類異常,則方法的異常說(shuō)明中無(wú)需指定這些異常;
???? (3) 由于 RuntimeException 及其派生類無(wú)需程序員顯式拋出,因此,編譯器不會(huì)給予 try-catch-finally 提示; 程序員可能不會(huì)去捕獲這樣的異常,從而使這些RuntimeException 通過(guò)重重關(guān)卡逃出 Main() 而未被捕獲, 此時(shí)程序?qū)⒆詣?dòng)調(diào)用該異常的printStackTrace,并終止程序;
?? ? (4) RuntimeException 及其派生異常通常代表程序中的錯(cuò)誤,比如 數(shù)組的 IndexOutOfBoundsException 異常;應(yīng)盡量避免出現(xiàn)此類異常。
?
??? 11.? 在構(gòu)造器中拋出異常會(huì)導(dǎo)致非常棘手的問(wèn)題;因此,盡量不要在構(gòu)造器中拋出任何異常;盡量使構(gòu)造器能夠 100%的成功運(yùn)行。
?
??? 12.? 異常匹配: 當(dāng)異常發(fā)生時(shí),系統(tǒng)將使用new創(chuàng)建一個(gè)異常對(duì)象(像創(chuàng)建一個(gè)普通Java對(duì)象一樣),并獲得一個(gè)引用;接著,系統(tǒng)將中止當(dāng)前執(zhí)行路徑,而轉(zhuǎn)到相應(yīng)的異常處理程序中(類似中斷處理,但不會(huì)返回到原執(zhí)行路徑); 匹配哪個(gè)異常處理程序按以下規(guī)則:
??? (1) 通常從緊隨其后的一系列 catch 語(yǔ)句進(jìn)行搜索;搜索順序是按catch語(yǔ)句出現(xiàn)的先后順序;一旦匹配成功,就不再匹配后面的catch語(yǔ)句了;
?? (2) 匹配的準(zhǔn)則是: catch (B) 將捕獲一切 B 及其派生類對(duì)象 (遵循多態(tài)機(jī)制) ;反之, 若拋出 A, 則可以由 A 的一切父類對(duì)象來(lái)捕獲。先來(lái)先得。
?? (3) 異常屏蔽: 若拋出B對(duì)象,且 B ---> B1 ---> B2 ---> ... ---> Bn, --->表示繼承關(guān)系,則在該繼承層次上,越靠近B(更精準(zhǔn)匹配),其catch 語(yǔ)句的順序越應(yīng)放在前面(如果同時(shí)出現(xiàn)的話),即 catch 語(yǔ)句塊的順序應(yīng)該依次是 catch(B1),catch(B2), ..., catch(Bn)。比如 RuntimeException 應(yīng)置于 Exception 之前,因?yàn)?Exception 可以捕獲一切異常,這就是說(shuō),若順序是:... catch(Exception e ) { // } catch (RuntimeException e) { } , RuntimeException 將沒(méi)有執(zhí)行的機(jī)會(huì)。
?
?? 13. 異常使用準(zhǔn)則: 避免立即捕獲和處理異常,而是將它交由合適的層次進(jìn)行處理。因?yàn)殄e(cuò)誤處理的抉擇可能涉及到系統(tǒng)整體的設(shè)計(jì),而不是局部的問(wèn)題。這類似于公司的客戶投訴中心:問(wèn)題通常不一定是由最底層人員的接收者來(lái)處理,而是一層層提交給更合適的某個(gè)管理層進(jìn)行處理。
?
?? 14. 受檢異常及其處理方法: 通俗地說(shuō), 非 RuntimeException 異常都是受檢異常,它在編譯時(shí)被檢查出來(lái),必須立即進(jìn)行處理:要么 提交給更高層,要么立即在緊隨其后的catch 語(yǔ)句進(jìn)行處理。 受檢異常帶來(lái)的麻煩是,有時(shí),你并沒(méi)有足夠的信息來(lái)進(jìn)行決策和處理(必須提交到更高層),或者根本不想進(jìn)行處理(試想你調(diào)用某個(gè)人的方法,該方法拋出異常,而你會(huì)覺(jué)得這似乎不關(guān)自己的事情)。
?????? 受檢異常有兩種處理方法: 傳遞到控制臺(tái),main() throws XXXException ; 或者將其包裝成 RuntimeException 。采用后者,你并不會(huì)丟棄異常(not to be silently swallowed),方法中也不必指定異常說(shuō)明,并且,產(chǎn)生的異常仍然被保留下來(lái)。但在某個(gè)地方,你仍然需要去處理它。
?
??? 15.? 錯(cuò)誤處理的思考: 最理想的錯(cuò)誤處理應(yīng)該是怎樣的呢? 程序中應(yīng)織有一張恢恢疏而不露的天網(wǎng),程序中的所有錯(cuò)誤都能夠被捕獲,并在合適的地方得到處理。結(jié)合 Java 的異常處理機(jī)制: A. 在可能出現(xiàn)錯(cuò)誤的地方拋出異常,避免立即進(jìn)行處理(除非有足夠信息能夠確知如何進(jìn)行處理); B. 當(dāng)捕獲到異常時(shí),如果確知如何處理,用catch塊進(jìn)行處理;否則,應(yīng)該將其封裝并重新拋出,提交給更高層進(jìn)行處理。
?
??? 16.? 《Thinking In Java》: 語(yǔ)言可以提供一些好的特性供程序員運(yùn)用,但最終的使用權(quán)在程序員手上。 A good language should help programmers program well , but no languge could prevent programmers from bad practice. 學(xué)習(xí)一門(mén)語(yǔ)言,不僅僅是掌握其語(yǔ)法和用法,更要領(lǐng)悟其設(shè)計(jì)思想,避開(kāi)語(yǔ)言設(shè)計(jì)的不足和陷阱,使用語(yǔ)言的優(yōu)良特性編寫(xiě)可靠、可維護(hù)的系統(tǒng)。
?
轉(zhuǎn)載于:https://www.cnblogs.com/lovesqcc/archive/2011/04/04/4037849.html
總結(jié)
以上是生活随笔為你收集整理的Java 异常处理学习总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2010所有用户
- 下一篇: Java WEB之Servlet学习之路