




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、摘要:本文從Java異常最基本的概念、語法開始講述了Java異常處理的基本知識,分析了Java異常體系結構,對比Spring的異常處理框架,闡述了異常處理的基本原則。并且作者提出了自己處理一個大型應用系統(tǒng)異常的思想,并通過設計一個異常處理的框架來論述此思想。一、 異常的概念和Java異常體系結構異常是程序運行過程中出現(xiàn)的錯誤。本文主要講授的是Java語言的異常處理。Java語言的異常處理框架,是Java語言健壯性的一個重要體現(xiàn)。Java把異常當作對象來處理,并定義一個基類java.lang.Throwable作為所有異常的超類。在Java API中已經(jīng)定義了許多異常類,這些異常類分為兩大類,錯
2、誤Error和異常Exception。Java異常體系結構呈樹狀,其層次結構圖如圖 1所示:圖 1 Java異常體系結構Thorwable類所有異常和錯誤的超類,有兩個子類Error和Exception,分別表示錯誤和異常。其中異常類Exception又分為運行時異常(RuntimeException)和非運行時異常,這兩種異常有很大的區(qū)別,也稱之為不檢查異常(Unchecked Exception)和檢查異常(Checked Exception)。下面將詳細講述這些異常之間的區(qū)別與聯(lián)系:1、Error與ExceptionError是程序無法處理的錯誤,比如OutOfMemoryError、T
3、hreadDeath等。這些異常發(fā)生時,Java虛擬機(JVM)一般會選擇線程終止。Exception是程序本身可以處理的異常,這種異常分兩大類運行時異常和非運行時異常。程序中應當盡可能去處理這些異常。2、運行時異常和非運行時異常運行時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯誤引起的,程序應該從邏輯角度盡可能避免這類異常的發(fā)生。非運行時異常是RuntimeException以外的異常,類型上都屬于
4、Exception類及其子類。從程序語法角度講是必須進行處理的異常,如果不處理,程序就不能編譯通過。如IOException、SQLException等以及用戶自定義的Exception異常,一般情況下不自定義檢查異常。二、 異常的捕獲和處理Java異常的捕獲和處理是一個不容易把握的事情,如果處理不當,不但會讓程序代碼的可讀性大大降低,而且導致系統(tǒng)性能低下,甚至引發(fā)一些難以發(fā)現(xiàn)的錯誤。Java異常處理涉及到五個關鍵字,分別是:try、catch、finally、throw、throws。下面將驟一介紹,通過認識這五個關鍵字,掌握基本異常處理知識。1、 異常處理的基本語法在java中,異常處理的
5、完整語法是:try/(嘗試運行的)程序代碼catch(異常類型 異常的變量名)/異常處理代碼finally/異常發(fā)生,方法返回之前,總是要執(zhí)行的代碼以上語法有三個代碼塊:try語句塊,表示要嘗試運行代碼,try語句塊中代碼受異常監(jiān)控,其中代碼發(fā)生異常時,會拋出異常對象。catch語句塊會捕獲try代碼塊中發(fā)生的異常并在其代碼塊中做異常處理,catch語句帶一個Throwable類型的參數(shù),表示可捕獲異常類型。當try中出現(xiàn)異常時,catch會捕獲到發(fā)生的異常,并和自己的異常類型匹配,若匹配,則執(zhí)行catch塊中代碼,并將catch塊參數(shù)指向所拋的異常對象。catch語句可以有多個,用來匹配多個
6、中的一個異常,一旦匹配上后,就不再嘗試匹配別的catch塊了。通過異常對象可以獲取異常發(fā)生時完整的JVM堆棧信息,以及異常信息和異常發(fā)生的原因等。finally語句塊是緊跟catch語句后的語句塊,這個語句塊總是會在方法返回前執(zhí)行,而不管是否try語句塊是否發(fā)生異常。并且這個語句塊總是在方法返回前執(zhí)行。目的是給程序一個補救的機會。這樣做也體現(xiàn)了Java語言的健壯性。2、 try、catch、finally三個語句塊應注意的問題第一、try、catch、finally三個語句塊均不能單獨使用,三者可以組成 try.catch.finally、try.catch、try.finally三種結構,c
7、atch語句可以有一個或多個,finally語句最多一個。第二、try、catch、finally三個代碼塊中變量的作用域為代碼塊內(nèi)部,分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。第三、多個catch塊時候,只會匹配其中一個異常類并執(zhí)行catch塊代碼,而不會再執(zhí)行別的catch塊,并且匹配catch語句的順序是由上到下。 3、throw、throws關鍵字throw關鍵字是用于方法體內(nèi)部,用來拋出一個Throwable類型的異常。如果拋出了檢查異常,則還應該在方法頭部聲明方法可能拋出的異常類型。該方法的調(diào)用者也必須檢查處理拋出的異常。如果所有方法都層層
8、上拋獲取的異常,最終JVM會進行處理,處理也很簡單,就是打印異常消息和堆棧信息。如果拋出的是Error或RuntimeException,則該方法的調(diào)用者可選擇處理該異常。有關異常的轉(zhuǎn)譯會在下面說明。throws關鍵字用于方法體外部的方法聲明部分,用來聲明方法可能會拋出某些異常。僅當拋出了檢查異常,該方法的調(diào)用者才必須處理或者重新拋出該異常。當方法的調(diào)用者無力處理該異常的時候,應該繼續(xù)拋出,而不是囫圇吞棗一般在catch塊中打印一下堆棧信息做個勉強處理。下面給出一個簡單例子,看看如何使用這兩個關鍵字:public static void test3() throws Exception/拋出一
9、個檢查異常throw new Exception("方法test3中的Exception"); 3、 Throwable類中的常用方法getCause():返回拋出異常的原因。如果 cause 不存在或未知,則返回 null。getMessage():返回異常的消息信息。printStackTrace():對象的堆棧跟蹤輸出至錯誤輸出流,作為字段 System.err 的值。三、 異常處理的一般原則1、 能處理就早處理,拋出不去還不能處理的就想法消化掉或者轉(zhuǎn)換為RuntimeException處理。因為對于一個應用系統(tǒng)來說,拋出大量異常是有問題的,應該從程序開發(fā)角度盡可能的
10、控制異常發(fā)生的可能。2、 對于檢查異常,如果不能行之有效的處理,還不如轉(zhuǎn)換為RuntimeException拋出。這樣也讓上層的代碼有選擇的余地可處理也可不處理。3、 對于一個應用系統(tǒng)來說,應該有自己的一套異常處理框架,這樣當異常發(fā)生時,也能得到統(tǒng)一的處理風格,將優(yōu)雅的異常信息反饋給用戶。四、 異常的轉(zhuǎn)譯與異常鏈1、異常轉(zhuǎn)譯的原理所謂的異常轉(zhuǎn)譯就是將一種異常轉(zhuǎn)換另一種新的異常,也許這種新的異常更能準確表達程序發(fā)生異常。在Java中有個概念就是異常原因,異常原因?qū)е庐斍皰伋霎惓5哪莻€異常對象,幾乎所有帶異常原因的異常構造方法都使用Throwable類型做參數(shù),這也就為異常的轉(zhuǎn)譯提供了直接的支持,
11、因為任何形式的異常和錯誤都是Throwable的子類。比如將SQLException轉(zhuǎn)換為另外一個新的異常DAOException,可以這么寫:先自定義一個異常DAOException:public class DAOException extends RuntimeException /(省略了部分代碼)public DAOException(String message, Throwable cause) super(message, cause);比如有一個SQLException類型的異常對象e,要轉(zhuǎn)換為DAOException,可以這么寫:DAOException daoEx = n
12、ew DAOException ( "SQL異常", e);異常轉(zhuǎn)譯是針對所有繼承Throwable超類的類而言的,從編程的語法角度講,其子類之間都可以相互轉(zhuǎn)換。但是,從合理性和系統(tǒng)設計角度考慮,可將異常分為三類:Error、Exception、RuntimeException,筆者認為,合理的轉(zhuǎn)譯關系圖應該如圖 2:圖 2 異常轉(zhuǎn)譯為什么要這么做呢?筆者認為,異常的處理存在著一套哲學思想:對于一個應用系統(tǒng)來說,系統(tǒng)所發(fā)生的任何異?;蛘咤e誤對操作用戶來說都是系統(tǒng)"運行時"異常,都是這個應用系統(tǒng)內(nèi)部的異常。這也是異常轉(zhuǎn)譯和應用系統(tǒng)異常框架設計的指導原則。在
13、系統(tǒng)中大量處理非檢查異常的負面影響很多,最重要的一個方面就是代碼可讀性降低,程序編寫復雜,異常處理的代碼也很蒼白無力。因此,很有必要將這些檢查異常Exception和錯誤Error轉(zhuǎn)換為RuntimeException異常,讓程序員根據(jù)情況來決定是否捕獲和處理所發(fā)生的異常。圖中的三條線標識轉(zhuǎn)換的方向,分三種情況:Error到Exception:將錯誤轉(zhuǎn)換為異常,并繼續(xù)拋出。例如Spring WEB框架中,將org.springframework.web.servlet.DispatcherServlet的doDispatch()方法中,將捕獲的錯誤轉(zhuǎn)譯為一個NestedServletExcep
14、tion異常。這樣做的目的是為了最大限度挽回因錯誤發(fā)生帶來的負面影響。因為一個Error常常是很嚴重的錯誤,可能會引起系統(tǒng)掛起。:Exception到RuntimeException:將檢查異常轉(zhuǎn)換為RuntimeException可以讓程序代碼變得更優(yōu)雅,讓開發(fā)人員集中經(jīng)理設計更合理的程序代碼,反過來也增加了系統(tǒng)發(fā)生異常的可能性。:Error到RuntimeException:目的還是一樣的。把所有的異常和錯誤轉(zhuǎn)譯為不檢查異常,這樣可以讓代碼更為簡潔,還有利于對錯誤和異常信息的統(tǒng)一處理。1、 異常鏈異常鏈顧名思義就是將異常發(fā)生的原因一個傳一個串起來,即把底層的異常信息傳給上層,這樣逐層拋出。
15、Java API文檔中給出了一個簡單的模型:try lowLevelOp(); catch (LowLevelException le) throw (HighLevelException)new HighLevelException().initCause(le);當程序捕獲到了一個底層異常le,在處理部分選擇了繼續(xù)拋出一個更高級別的新異常給此方法的調(diào)用者。這樣異常的原因就會逐層傳遞。這樣,位于高層的異常遞歸調(diào)用getCause()方法,就可以遍歷各層的異常原因。這就是Java異常鏈的原理。異常鏈的實際應用很少,發(fā)生異常時候逐層上拋不是個好注意,上層拿到這些異常又能奈之何?而且異常逐層上拋會
16、消耗大量資源,因為要保存一個完整的異常鏈信息。五、 設計一個高效合理的異常處理框架對于一個應用系統(tǒng)來說,發(fā)生所有異常在用戶看來都是應用系統(tǒng)內(nèi)部的異常。因此應該設計一套應用系統(tǒng)的異常框架,以處理系統(tǒng)運行過程中的所有異常。基于這種觀點,可以設計一個應用系統(tǒng)的異常比如叫做AppException。并且對用戶來說,這些異常都是運行應用系統(tǒng)運行時發(fā)生的,因此AppException應該繼承RuntimeException,這樣系統(tǒng)中所有的其他異常都轉(zhuǎn)譯為AppException,當異常發(fā)生的時候,前端接收到AppExcetpion并做統(tǒng)一的處理。畫出異常處理框架如圖 3 :圖 3 一個應用系統(tǒng)的異常處理
17、框架在這個設計圖中,AppRuntimeException是系統(tǒng)異常的基類,對外只拋出這個異常,這個異??梢杂汕岸耍蛻舳耍┙邮仗幚?,當異常發(fā)生時,客戶端的相關組件捕獲并處理這些異常,將"友好"的信息展示給客戶。在AppRuntimeException下層,有各種各樣的異常和錯誤,最終都轉(zhuǎn)譯為AppRuntimeException,AppRuntimeException下面還可以設計一些別的子類異常,比如AppDAOException、OtherException等,這些都根據(jù)實際需要靈活處理。在往下就是如何將捕獲的原始異常比如SQLException、HibernateException轉(zhuǎn)換為更高級一點AppDAOException。有關異常框架設計這方面公認比較好的就是Spring,Spring中的所有異常都可以用org.springframework.core.NestedRuntimeException來表示,并且該基類繼承的是RuntimeException。Spring框架很龐大,因此設計了很多NestedRuntimeException的子類,還有異常轉(zhuǎn)換的工具,這些都是非常優(yōu)秀的設計思想。六、 Java異常處理總結回顧全文,總結一下Java異常處理的要點:1、 異常是程序運行過程過程
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年 二手房產(chǎn)買賣合同
- 2025年4個兄弟分家協(xié)議書模板
- 三年級上冊數(shù)學教案-8.1 分數(shù)的初步認識 ︳西師大版
- 2025年固始縣再就業(yè)小額擔保貸款協(xié)議
- 2025年廣東理工職業(yè)學院單招職業(yè)適應性測試題庫及答案一套
- 2025年河南機電職業(yè)學院單招職業(yè)傾向性測試題庫必考題
- 2025云南省建筑安全員-C證考試題庫
- 健身中心鏈家居間服務合同
- 2025年度中小企業(yè)擔保合同解除協(xié)議書
- 2025年度文化創(chuàng)意產(chǎn)品采購合同甲方責任與市場推廣
- GB/T 32399-2024信息技術云計算參考架構
- 初中體育與健康 初二 水平四(八年級)田徑大單元教學設計+快速跑教案
- 2024-2025學年華東師大版數(shù)學七年級上冊計算題專項訓練
- 移動通信運營商倉庫安全管理制度
- DL∕T 5452-2012 變電工程初步設計內(nèi)容深度規(guī)定
- 人工智能產(chǎn)業(yè)分類目錄
- 中國急性缺血性卒中診治指南(2023)解讀
- 一年級下冊口算題卡大全(50套直接打印版)
- 一年級下冊寫字表練字帖
- 2024PowerTitan系列運維指導儲能系統(tǒng)運維指導
評論
0/150
提交評論