




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第5章異常5.1編程中的錯誤5.2異常與異常類5.3異常的處理5.4異常地拋出5.5應(yīng)用舉例5.1編程中的錯誤程序中出現(xiàn)的錯誤必須要處理,否則程序會錯誤退出或帶來錯誤的結(jié)果和狀態(tài),造成越來越多的異?,F(xiàn)象。根據(jù)錯誤的性質(zhì)和特點,—般可把錯誤分為編譯錯誤和運行錯誤兩種。5.1.1編譯錯誤編譯錯誤是由于所編碼的程序存在語法問題,未能通過內(nèi)源代碼到目標(biāo)碼的編譯過程而產(chǎn)生的,它是由語言的編譯系統(tǒng)負責(zé)檢測和報告。下一頁返回5.1編程中的錯誤每種計算機高級語言都有自己的語法規(guī)范,編譯系統(tǒng)就根據(jù)這個規(guī)范來檢查編程人員所書寫的源代碼(程序)是否符合既定的標(biāo)準(zhǔn)。有的高級語言的語法規(guī)定得比較嚴(yán)格,有的語言則給編程人員很大的自由度,如C語言,程序可以寫得很靈活,使編程者可充分發(fā)揮他們的核心和能力。Java語言是定位于網(wǎng)絡(luò)計算的安全性要求較高的語言,它的語法規(guī)范設(shè)計得比較全面,相對于C語言增加了不少規(guī)定。例如,數(shù)組元素下標(biāo)越界檢查、檢查對未開辟空間對象的使用等。由于更多的檢查工作由系統(tǒng)自動完成,可以減少編程者的設(shè)計負擔(dān)和程序中的隱含錯誤,提高初學(xué)者編程的成功率。上一頁下一頁返回5.1編程中的錯誤大部分編譯錯誤是由于對語法不熟悉或拼寫失誤等引起的,例如在Java語言中規(guī)定:需在每個句子的末尾使用分號,標(biāo)識符區(qū)分大小寫,如果不注意這些細杰,就會引發(fā)編譯錯誤。由于編譯系統(tǒng)會給出每個編譯錯誤的位置和相關(guān)的錯誤信息,所以修改編譯錯誤相對較簡單;但同時由于編譯系統(tǒng)判定錯誤比較機械,再參考他所指出的錯誤地點和信息時應(yīng)靈活的同時參照上下文其他語句,將程序作為一個整體來檢查。沒有編譯錯誤是一個程序能正常運行的基本條件,只有所有的編譯錯誤都改正了,源代碼才可以被成功的編譯成目標(biāo)代碼或字節(jié)代碼。上一頁下一頁返回5.1編程中的錯誤5.1.2運行錯誤一個沒有編譯錯誤的可執(zhí)行或解釋的程序,距離完全正確的程序通常還有一段距離,這是因為排除了編譯錯誤,程序中可能還存在著運行錯誤。運行錯誤是在程序的運行過程中產(chǎn)生的錯誤。根據(jù)性質(zhì)不同,運行錯誤還可分為系統(tǒng)運行錯誤和邏輯運行錯誤。上一頁下一頁返回5.1編程中的錯誤系統(tǒng)錯誤是指程序在執(zhí)行過程中引發(fā)了操作系統(tǒng)的問題。應(yīng)用程序是工作在計算機的操作系統(tǒng)平臺上的,如果應(yīng)用程序運行時所產(chǎn)生的運行錯誤危及操作系統(tǒng),對操作系統(tǒng)產(chǎn)生損害,就有可能造成整個計算機的癱瘓,例如死機、死循環(huán)等。所以不排除系統(tǒng)運行錯誤,程序就不能正常地工作。系統(tǒng)運行錯誤通常比較隱秘,排除時應(yīng)根據(jù)錯誤的現(xiàn)象,結(jié)合源程序仔細判斷。例如,出現(xiàn)死循環(huán),就應(yīng)該檢測源程序中的循環(huán)語句及其中止條件;出現(xiàn)死機,就應(yīng)該檢查程序中的內(nèi)存分配處理語句等。上一頁下一頁返回5.1編程中的錯誤排除了系統(tǒng)運行錯誤,程序可以順利執(zhí)行了,卻仍然不能代表它已經(jīng)毫無問題了。因為程序中還有可能存在著邏輯運行錯誤。邏輯運行錯誤是指程序不能實現(xiàn)編程人員的設(shè)計意圖和設(shè)計功能而產(chǎn)生的錯誤,例如排序時不能正確處理數(shù)組頭后的元素等。有些邏輯運算錯誤是由于算法考慮不周引起的,也有些則來自編碼過程中的疏忽。排除運行錯誤時,一個非常有效和常用的手段是使用開發(fā)環(huán)境所提供的單步運行機制和設(shè)置斷點功能來分解程序運行過程,使之在人為的控制下邊調(diào)試邊運行。在調(diào)試過程中,調(diào)試者可以隨時檢查變量中保存的中間量,設(shè)置臨時運行環(huán)境,一步一步地檢查程序的執(zhí)行過程,從而挖出隱藏的錯誤。上一頁返回5.2異常與異常類5.2.1異常處理機制概述異常就是在程序的運行過程中所發(fā)生的異常事件(不正?,F(xiàn)象),它中斷指令的正常執(zhí)行。在Java程序的執(zhí)行過程中,如果出現(xiàn)了異常事件,就會生成一個異常對象,故又稱為特殊的運行錯誤對象。很多類型的錯誤也都會導(dǎo)致異常的產(chǎn)生,如需要打開的文件不存在、內(nèi)存不夠、數(shù)據(jù)訪問超界、嚴(yán)重者導(dǎo)致硬盤崩潰等,都會影響程序的正常執(zhí)行。在網(wǎng)絡(luò)環(huán)境中運行的Java程序,安全是首先考慮的重要元素之一。為了能夠及時有效地處理程序中的遠行錯誤,Java中通過引入異常和異常類來處理。作為面向?qū)ο蟮恼Z言,異常與其他語言要素一樣,是面向?qū)ο笠?guī)范的一部分,是異常類的對象。下一頁返回5.2異常與異常類Java中定義了很多異常類,每個異常類都代表了一種運行錯誤,類中包含了該運行錯誤的信息和處理錯誤的方法等內(nèi)容。每當(dāng)Java程序運行過程中發(fā)生一個可識別的運行錯誤時,即該錯誤有一個異常與之相對應(yīng)時,系統(tǒng)都會產(chǎn)生一個相應(yīng)的該異常類的對象,即產(chǎn)生一個異常。一旦一個異常對象產(chǎn)生了,系統(tǒng)中就一定有相應(yīng)的機制來處理它,確保不會產(chǎn)生死機、死循環(huán)或其他對操作系統(tǒng)的損害,從而保證了整個程序運行的安全性。這就是java的異常處理機制。如在例5-1中,當(dāng)我們在一個文件上建立文件輸入流時,如果這個文件并不存在,異常就會生成,另外,在從文件中讀取數(shù)據(jù)時,也可能發(fā)生I/O異常。上一頁下一頁返回5.2異常與異常類[例5-1]文件操作異常。Importjava.io.*;ClassExceptionDemol{Publicstaticvoidmain(Stringargs[]){FileInputStreamFis=nesFileInputStream(“text”);Intb;While((b=fis.read())!=-1){System.out.print(b);}Fis.close();}}上一頁下一頁返回5.2異常與與異常類當(dāng)我們編譯這這個程序時,,屏幕上會輸輸出下面的信信息:ExceptionDemo1.Java:6:Exceptionjava.io.FileNotFoundExceptionmustbecaught,oritmustbedeclaredinthethrowsclauseofthismethod.FileInputStreamfis=newFileInputStream(“text”);^ExceptionDemol.java:8:Exceptionjava.io.IOExceptionmustbecaught,oritmustbedeclaredinthethrowsclauseofthismethod.While((b=fis.read())!=-1){^上一頁下一頁返回5.2異常與與異常類2errors在Java程程序的執(zhí)行過過程中,異常常對象可能是是由正在運行行的方法生成成,也可能由由Java虛虛擬機生成,,其中包含一一些信息指明明異常事件的的類型以及當(dāng)當(dāng)異常發(fā)生時時程序的運行行狀態(tài)等。生生成的異常對對象將傳遞給給Java運運行時系統(tǒng),,這一異常的的產(chǎn)生和提交交過程稱為拋拋出(throw)異常常。當(dāng)Java運運行時系統(tǒng)得得到一個異常常對象時,它它將會尋找處處理這一異常常的代碼。尋尋找的過程從從生成異常對對象的代碼塊塊開始,沿著著方法的調(diào)用用棧逐層回溯溯,直到找到到一個方法能能夠處理這種種類型的異常常為止。然后后運行時系統(tǒng)統(tǒng)把當(dāng)前異常常對象交給這這個方法進行行處理。這一一過成稱為捕捕獲(catch)異常常。如果Java運行時系統(tǒng)統(tǒng)找不到可以以捕獲異常的的方法,則運運行時系統(tǒng)將將終止,相應(yīng)應(yīng)的Java程序也將退退出。例5-2中出現(xiàn)的的即為這種情情況。上一頁下一頁返回5.2異常與與異常類[例5-2]當(dāng)0作為為除數(shù)時,會會發(fā)生除零溢溢出的異常事事件,使程序序無法繼續(xù)運運行。ClassExceptionDem02{Publicstaticvoidmain(Stringargs[]){Inta==();System.out.println(5/a);}}我們編譯這個個程序得到其其字節(jié)碼文件件,然后運行行它,屏幕上上的顯示如下下:java.Lang.ArthmeticException:/byzeroatExceptionDemo2.main(ExceptionDemo2.Java:4)上一頁下一頁返回5.2異常與與異常類在上面的兩個個例子中,我我們都遇到了了異常。屏幕幕上所顯示的的信息:java.ioFileNotFoundException,java.io.IOException以及java.LangArlthmeticException分別指明了異異常的類型。。同時我們也也可以看到,,對于一些異異常,在程序序中必須對它它進行處理,,否則編譯程程序會指出錯錯誤(如例5-1)。但但對另一些異異常,在程序序中可以不做做處理,而直直接由運行時時系統(tǒng)來處理理(如例5-2)。使用異常處理理程序出錯有有以下兩個原原因:一是將將錯誤處理程程序與正常程程序流分開,,增加程序的的可讀性和可可維護性;二二是可容易的的指出異常在在何處處理。。上一頁下一頁返回5.2異常與與異常類5.2.2異異常類結(jié)構(gòu)構(gòu)與組成在java類類庫的每個包包中都定義了了異常類,所所有這些類都都是類Throwable的子類。。Throwable類類屬于類庫java.lang包中中的一個類,,在程序中不不必使用import語語句引入即可可食用。Throwable類派生生了兩個子類類:Exception和Error。其中Error類類由系統(tǒng)保留留,而Exception類則供應(yīng)應(yīng)用程序使用用。Java作為面向?qū)ο笤O(shè)計語言言,它定義了了很多標(biāo)準(zhǔn)的的異常處理類類,采用捕獲獲-拋出(catch-throw)方式,捕捕獲并處理異異常。上一頁下一頁返回5.2異常與與異常類Error類類的子類有后后綴Error,它們用用于指示異常常系統(tǒng)條件。。例如OutOfMemoryError表示虛擬擬機內(nèi)存超界界,內(nèi)存單元元收集程序無無法獲得更多多的內(nèi)存:StackOverFlowError表示翻譯器器中堆棧溢出出。這些Error類的的子類包括動動態(tài)鏈接失敗敗、虛擬機錯錯誤等,通常常Java程程序不捕獲這這些異常,也也不會拋出這這種異常。一一般來說,這這些異常是不不可修復(fù)的,,不易處理。。Exception類的的子類一般是是可以修復(fù)的的。例如EOFException表示打開開的文件不再再有可讀數(shù)據(jù)據(jù);FileNorFoundException表示打開的的文件在文件件系統(tǒng)中不存存在。這一子子類是Java程序中所所大量處理的的異常。并且且同其他的類類一樣,Exception類有自自己的方法和和屬性。他的的構(gòu)造函數(shù)有有兩個:上一頁下一頁返回5.2異常與與異常類[格式]publicException();PublicException(Strings);[說明]第第二個接受字字符串參數(shù)傳傳入的信息,,通常是對該該異常所對應(yīng)應(yīng)錯誤的描述述。Exception類從從父類Throwable那里還繼繼承了若干方方法,其中常常用的有:[格式]publicStringtoString();;[說明]顯顯示異常信息息以及getMessage()返返回信息的簡簡短描述的字字符串。[格式]publicvoidprintStackTrace();[說明]打打印異常發(fā)生生處堆棧跟蹤蹤信息,包括括異常的類名名、方法名及及所在程序的的行數(shù),沒有有返回值,實實際上它的功功能是完成一一個打印操作作,在當(dāng)前的的標(biāo)準(zhǔn)輸出((一般就是屏屏幕)上打印印輸出當(dāng)前異異常對象的堆堆棧使用軌跡跡,也即程序序先后調(diào)用執(zhí)執(zhí)行了哪些對對象或類的那那些方法,使使得運算過程程中產(chǎn)生了這這個異常對象象。上一頁下一頁返回5.2異常與與異常類[格式]publicStingGetMessage();[說明]獲獲得與異常和和錯誤相關(guān)的的更詳細的錯錯誤信息,但但非每個異常常都有詳細信信息。如果沒沒有詳細信息息,該方法調(diào)調(diào)用后返回空空值。5.2.3系系統(tǒng)定義的的運行異常Exception類有有若干子類,,每一個子類類代表了一種種特定的運行行時異常。其其中有些是系系統(tǒng)實現(xiàn)定義義好并包含在在Java類類庫中的,稱稱為系統(tǒng)定義義的運行異常常。系統(tǒng)定義的運運行異常通常常對應(yīng)著系統(tǒng)統(tǒng)運行錯誤。。由于這種錯錯誤可能導(dǎo)致致操作系統(tǒng)錯錯誤甚至ishi整個系系統(tǒng)的癱瘓,,如例5-1所涉及到的的FileNotFoundException和和IOException。對于于這類異常來來說,如果程程序不進行處處理,可能會會帶來意想不不到的結(jié)果,,所以定義異異常類來特別別處理,下面面列出若干常常見的系統(tǒng)定定義運行異常常:上一頁下一頁返回5.2異常與與異常類ClassNotFoundException:未找到欲裝裝載使用的類類異常。ArrayIndexOnOfBoundsException:數(shù)數(shù)組越界異常常,即小雨或或超過數(shù)組界界限使用。FileNotFoundException:引引用空的尚無無內(nèi)存空間的的對象異常。。ArithmeticException::零件為除數(shù)數(shù)等算術(shù)異常常。IntcrruptedException:線程在睡睡眠、等待或或其他原因暫暫停時被其他他線程掃斷。。UnknownHostException:無法法確定主機的的IP地址異異常。SecurityException:安全全性異常,如如Applet欲讀寫文文件。MalfornedURLException:URL格式異常常。StringIndexOutOfBoundsException:訪問String或或StringBuffer字符符時,索引小小于零或超過過字符串長度度。上一頁下一頁返回5.2異常常與異常類類[例5-3]測試試異常程序序。importjava.io.*;PublicclassExceptionTest{publicstaticvoidmain(Stringargs[]){For(inti-0;i<4;i++){Intk;Try{Switch(i){Case();//dividedbyzero上一頁下一頁返回5.2異常常與異常類類Intzero=0;K=911/zero;Break;Case1;//nullpointerIntb[]=null;K=b[0];Break;Case2;//arrayindexoutofboundIntc[]=newint[2];K=c[9];Break;上一頁下一頁返回5.2異常常與異常類類Case3;//stringindexoutofboundCharch-““abc””.charAt(99);Break;}}catch(Exceptione){System.out.printIn(“\nTestcase#””+i+””\n”);System.out.printIn(e);}}}}上一頁下一頁返回5.2異常常與異常類類運行測試程程序的輸出出結(jié)果如下下:Testcase#0Java.lang.ArithmeticException:/byzeroTestcase#1Java.lang.NullPointerException;Testcase#2Java.lang.ArrayIndexOutOfBounesExceptionTestcase#3上一頁下一頁返回5.2異常常與異常類類Java.lang.StringIndexOutOfBoundsException:Stingindesoutofrange:99由于定義了了相應(yīng)的異異常,Java程序序即使產(chǎn)生生一些致命命的錯誤,,如引用空空對象的等等,系統(tǒng)也也會自動產(chǎn)產(chǎn)生一個對對應(yīng)的異常常對象來處處理和控制制這個錯誤誤,避免其其蔓延或產(chǎn)產(chǎn)生更大的的問題。5.2.4用戶自自定義的異異常對于某個應(yīng)應(yīng)用所特有有的運行錯錯誤,則需需要編程人人員根據(jù)程程序的特殊殊邏輯在用用戶程序里里自己創(chuàng)建建用戶自定定義的異常常類和異常常對象。這這種用戶自自定義異常常主要用來來處理用戶戶程序中特特定的邏輯輯運行錯誤誤。定義一個Employee類類的構(gòu)造函函數(shù):上一頁下一頁返回5.2異常常與異常類類Employee((Stringname,,doubleinitSal){//有有兩個參數(shù)數(shù)的構(gòu)造函函數(shù),利用用這兩個參參數(shù)初始化化//雇員姓姓名、工資資并初始化化雇員編號號This();m_EmpName=newString(name);If(initSal<m,MinSalary)System.exit(0);M_EmpSalary=initSal;}上一頁下一頁返回5.2異常常與異常類類在這個方法法里,一旦旦給出的雇雇員工資初初值不符合合最低工資資的規(guī)定,,則直接退退出整個程程序的運行行。這樣處處理雖然保保證了程序序的邏輯正正確性,但但卻沒有給給出足夠的的錯誤提示示信息,如如果程序里里還有其他他類似的處處理,那么么當(dāng)產(chǎn)生錯錯誤退出運運行時,用用戶將無法法得知到底底是什么錯錯誤導(dǎo)致了了這次推出出,對于程程序的調(diào)試試和運行都都很不方便便。為了解解決這個問問題,我們們可以定義義一個用戶戶程序異常常IIIegalSalaryException,專專門處理上上述“發(fā)給給雇員的工工資低于系系統(tǒng)要求的的最低工資資”的邏輯輯錯誤。上一頁下一頁返回5.2異常常與異常類類PublicclassIllegatSalaryExceptionExtendsException{//自定義的的系統(tǒng)類Exception的子類PrivateEmploueem_ConcernedEmp://產(chǎn)生當(dāng)前前錯誤的Employee對對象的引用用Pribatedoublem_IllegalSalary;//產(chǎn)生當(dāng)前前錯誤的非非法的工資資數(shù)額IllegalSalaryException(){Super(“不合合法的起薪薪:低于最最低工資限限額”);;//調(diào)用用父類Exception的的構(gòu)造函數(shù)數(shù)}上一一頁頁下一一頁頁返回回5.2異異常常與與異異常常類類IllegalSalaryException(Employeeemp,doubleiSal){//構(gòu)構(gòu)造造函函數(shù)數(shù)This();M_ConcernedEmp=emp;//初初始始化化兩兩個個屬屬性性M_illegalSalary=iSal;}PublicStringtoString(){//重重載載父父類類的的方方法法,,給給出出詳詳細細的的錯錯誤誤信信息息Strings;;上一一頁頁下一一頁頁返回回5.2異異常與異異常類If(m_ConcernedEmp!=null)S=”為為雇員提提供非法法工資;;雇員號號_”+m_ComcernedEmp.getEmpNo()+”非法法工資數(shù)數(shù)額_””+m+IllegalSalary+””合法的的最低工工資數(shù)額額_”+Employee.getMinSalary();ElseS=”給給出的工工資初始始值不合合理,不不能創(chuàng)建建Employee對對象”;Returns;}}上一頁下一頁返回5.2異異常與異異常類用戶自定定義異常常用來處處理程序序中可能能產(chǎn)生的的邏輯錯錯誤,使使得這種種錯誤能能夠被系系統(tǒng)及時時識別并并處理,,而不致致造成更更大的影影響,從從而使用用戶程序序更為穩(wěn)穩(wěn)定,有有更靈活活的容錯錯性能,,并使整整個系統(tǒng)統(tǒng)更加安安全。創(chuàng)建用戶戶自定義義異常時時,一般般需要完完成如下下的工作作:(1)聲聲明一個個新的異異常類,,使之以以Exception類或其其他某個個已經(jīng)存存在的系系統(tǒng)異常常類或用用戶異常常類為父父類;(2)為為新的異異常類定定義屬性性和方法法,或重重載父類類的屬性性和方法法,使這這些屬性性和方法法能夠體體現(xiàn)該類類所對應(yīng)應(yīng)的錯誤誤的信息息。只有定義義了異常常類,系系統(tǒng)才能能夠識別別特定的的運行錯錯誤,才才能夠及及時地控控制和處處理運行行錯誤;;所以定定義足夠夠多的異異常類是是構(gòu)建一一個穩(wěn)定定完善的的應(yīng)用系系統(tǒng)的重重要基礎(chǔ)礎(chǔ)之一。。上一頁返回5.3異異常的處處理5.3.1try-catch-finally異常的處處理是通通過try-catch-finally語句實實現(xiàn)的。。其語法法為:[格式]try{正常程序序段;}catch((ExecptionName1e){//catch((異常常類1異常常變量))與異常類類1有關(guān)關(guān)的處理理程序段段;}catch((ExecptionName2e)與異常類類2有關(guān)關(guān)的處理理程序段段;}…下一頁返回5.3異異常的處處理}catch((ExceptionNamene)){與異常類類n有關(guān)關(guān)的處理理程序段段;}}finally{推出異常常程序段段;}[說明]在try-catch-finally語句句結(jié)構(gòu)中中,catch語句和和finally語句句是可選選的,但但是至少少要有一一個catch語句或或finally語句句。1、try捕獲異常常的第一一步是用用try{…}選定捕捕獲異常常的范圍圍,由try所所限定的的代碼塊塊中的語語句,在在執(zhí)行過過程中可可能會生生成異常常對象))(拋出出異常))。這個個try語句塊塊用來啟啟動java的的異常處處理機制制,可能能拋出異異常的語語句,包包括throw語句、、調(diào)用可可能拋出出異常方方法的調(diào)調(diào)用語句句,都應(yīng)應(yīng)該包含含在這個個try語句塊塊中。上一頁下一頁返回5.3異異常的處處理2、catch捕捉異異常當(dāng)一個異異常被拋拋出時,,應(yīng)該有有專門的的語句來來接收這這個被拋拋出的異異常對象象,這個個過程被被稱為捕捕捉異常常。當(dāng)一一個異常常類的對對象被捕捕捉獲接接收后,,用戶程程序就會會發(fā)生流流程的跳跳轉(zhuǎn),系系統(tǒng)中止止當(dāng)前的的流程而而跳轉(zhuǎn)至至專門的的異常處處理語句句塊,或或直接跳跳出當(dāng)前前程序和和Java虛擬擬機回到到操作系系統(tǒng)。Java語言規(guī)規(guī)定,每每個catch語句塊塊都應(yīng)該該與一個個try語句塊塊相對應(yīng)應(yīng),每個個try代碼塊塊也必須須伴隨一一個或多多個catch語句,,用于處處理try代碼碼塊中所所生成的的異常事事件。Catch語句句只需要要一個形形式參數(shù)數(shù),參數(shù)數(shù)類型指指明它能能夠捕獲獲的異常常類型,,這個類類必須是是Throwable的子類類,運行行時系統(tǒng)統(tǒng)通過參參數(shù)值把把被拋棄棄的異常常對象傳傳遞給catch塊。。其格式式如下::上一頁下一頁返回5.3異異常的處處理[格式]catch(異常常類名異異常形形式參數(shù)數(shù)名){與異常類類有關(guān)的的處理語語句組;;}因此,在在Java程序序里,異異常對象象是依靠靠以catch語句為為標(biāo)志的的異常處處理語句句塊來捕捕捉和處處理的。。異常處處理語句句塊又稱稱為catch語句塊塊。在catch塊中中是對異異常對象象進行處處理的代代碼,預(yù)預(yù)防為其其他對象象一樣,,可以訪訪問一個個異常對對象的變變量或調(diào)調(diào)用它的的方法。。GetMessage()是類類Throwable所提提供的方方法,用用來得到到有關(guān)異異常事件件的信息息,類Throwable還提供供了方法法printStackTrace()用來來跟蹤異異常事件件發(fā)生時時執(zhí)行堆堆棧的內(nèi)內(nèi)容。上一一頁頁下一一頁頁返回回5.3異異常常的的處處理理[例例5-4]捕捕捉捉并并處處理理異異常常。。Importjava.io.*;PublicclassTryTest{PublicTryTest(){Try{Inta[]=newint[2];a[4]=3;System.out.printIn(““Afterhandlingexceptionreturnhere?””);}catch(IndexOutOfBoundsExceptione){System.err.printIn(““exceptionmsg:””+e.gerMessage());System.er.printIn(““exceptionstring:””+e.toString());e.printStackTrace();}finally{上一一頁頁下一一頁頁返回回5.3異異常常的的處處理理System.out.printIn(““---------------------““);System.out.printIn(““finally””);}System.out.printIn(““Noexception?””);}Publicstaticvoidmain(Stringargs[]){NewTryTest();}}上一一頁頁下一一頁頁返回回5.3異異常常的的處處理理例5-4設(shè)設(shè)計計了了一一個個數(shù)數(shù)組組超超界界異異常常。。用用catch語語句句捕捕獲獲異異常常,,在在處處理理異異常常中中使使用用了了三三個個方方法法,,即即getMessage()、、toString()、、printStackTrace()來來顯顯示示錯錯誤誤信信息息。。從從程程序序的的運運行行結(jié)結(jié)果果可可知知,,當(dāng)當(dāng)catch捕捕獲獲到到異異常常,,進進行行處處理理后后,,程程序序并并沒沒有有恢恢復(fù)復(fù)到到產(chǎn)產(chǎn)生生異異常常的的地地方方,,而而是是執(zhí)執(zhí)行行try-catch-finally結(jié)結(jié)構(gòu)構(gòu)外外緊緊跟跟著著下下一一條條語語句句。。可見catch語句句塊應(yīng)應(yīng)該緊緊跟在在try語語句塊塊的后后面,,當(dāng)try語句句塊中中的某某條語語句在在執(zhí)行行時產(chǎn)產(chǎn)生了了一個個異常常時,,例如如a[]整整數(shù)數(shù)數(shù)組定定義為為2個個元素素,現(xiàn)現(xiàn)要賦賦一個個數(shù)3至第第4個個元素素處a[4],,數(shù)組組邊界界超界界,將將產(chǎn)生生并拋拋出異異常類類IndexOutOfBoundsException的的一個個對象象,此此時被被啟動動的異異常處處理機機制會會自動動捕捉捉到它它,然然后流流程自自動跳跳過產(chǎn)產(chǎn)生異異常的的語句句后面面的所所有尚尚未執(zhí)執(zhí)行語語句,,而轉(zhuǎn)轉(zhuǎn)至try塊后后面的的catch語語句塊塊,執(zhí)執(zhí)行catch塊中中的語語句。。上一頁頁下一頁頁返回5.3異常常的處處理3、finally捕獲異異常的的最后后一步步是通通過finally語句句為異異常處處理提提供一一個統(tǒng)統(tǒng)一的的出口口,使使得在在控制制流轉(zhuǎn)轉(zhuǎn)到程程序的的其他他部分分以前前,能能夠?qū)Τ绦蛐虻臓顮顟B(tài)作作統(tǒng)一一的管管理。。不論論在try代碼碼塊中中是否否發(fā)生生了異異常事事件,,finally塊塊中的的語句句都會會被執(zhí)執(zhí)行。。Finally語句句的存存在似似乎沒沒有必必要。。但是是如果果修改改前面面的例例5-2,,得在在try代代碼塊塊中生生成一一個除除0溢溢出的的異常常對象象。如如下所所示::Intb=0;System.out.printIn(5/b);上一頁下一頁返回5.3異異常的處處理當(dāng)程序運運行時,,由于生生成了ArithmeticException異常對對象,運運行時系系統(tǒng)將終終止執(zhí)行行,這時時打開的的文件流流將不會會被關(guān)閉閉,有可可能造成成對文件件的破壞壞。使用用finally語句句,我們們可以這這樣處理理:Finally{If(fis!=null){System.out.printIn(“closingFileInputStream…””);Fis.close():}else{System.out.printIn(“FileInputStreamnotopen”);}}這時程序序的運行行結(jié)果為為:上一頁下一頁返回5.3異異常的處處理ClosingFileINputStream……Java.lang.ArithmeticException:/buzeroAtExceptionDemoL.main(ExceptionDemol.java:10)也許你會會說,如如果用catch語句句捕獲這這一異常常,并在在其中關(guān)關(guān)閉文件件流不就就可以了了嗎?但但是,如如果在try代代碼塊中中有生成成其他異異常了呢呢?尤其其是生成成編譯器器不要求求你進行行處理的的運行時時異常了了呢?不不幸的是是運行時時異常常常常是大大量存在在的,如如在每個個catch語語句中分分別進行行處理會會使程序序變得冗冗長而失失去可讀讀性,給給程序的的維護造造成困難難。上一頁下一頁返回5.3異異常的處處理5.3.2多多異常的的處理一個try塊可可能產(chǎn)生生多種不不同的異異常,如如果希望望能采取取不同的的方法來來處理這這些異常常,就需需要使用用多異常常處理機機制。多多異常處處理是通通過在一一個try塊后后面定義義若干個個catch塊塊來實現(xiàn)現(xiàn)的,每每個catch塊用來來接收和和處理一一中特定定的異常常對象。。要想用不不同的catch塊來來分別處處理不同同的異常常對象,,首先要要求catch塊能夠夠區(qū)別這這些不同同的異常常對象,,并能判判斷一個個異常對對象是否否應(yīng)為本本塊接收收和處理理。這種種判斷功功能是通通過catch塊的參參數(shù)來實實現(xiàn)的。。上一頁下一頁返回5.3異常常的處理一個異常對對象能否被被一個catch語語句塊所接接收,主要要看該異常常對象與catch塊的異常常參數(shù)的匹匹配情況,,當(dāng)他們滿滿足下面三三個條件的的任何一個個是,異常常對象將被被接收:(1)異常常對象與參參數(shù)屬于相相同的異常常類;(2)異常常對象屬于于參數(shù)異常常類的子類類;(3)異常常對象實現(xiàn)現(xiàn)了參數(shù)所所定義的接接口。如果try塊產(chǎn)生的的異常對象象被第一個個catch塊所接接收,則程程序的流程程將直接跳跳轉(zhuǎn)到這個個catch語句塊塊中,語句句塊執(zhí)行完完畢后就推推出當(dāng)前方方法,try塊中尚尚未執(zhí)行的的語句和其其他的catch塊塊將被忽略略;如果try塊產(chǎn)產(chǎn)生的異常常對象與第第一個catch塊塊不匹配,,系統(tǒng)將自自動轉(zhuǎn)到第第二個catch塊塊進行匹配配,如果第第二個仍不不匹配,就就一直向下下導(dǎo)一個可可以接收該該異常對象象的catch塊,,完成流程程的跳轉(zhuǎn)。。上一頁下一頁返回5.3異常常的處理如果所有的的catch塊都不不能與當(dāng)前前的異常對對象匹配,,說明當(dāng)前前方法不能能處理這個個異常對象象,程序流流程將返回回到調(diào)用該該方法的上上層方法,,如果這個個上層方法法中定義了了與所產(chǎn)生生的異常對對象相匹配配的catch塊,,流程就跳跳轉(zhuǎn)到這個個catch塊中;;否則繼續(xù)續(xù)回朔更上上層的方法法,如果所所有的方法法中都找不不到合適的的catch塊,則則由Java運行系系統(tǒng)來處理理這個異常常對象。此此時通常會會中止程序序的執(zhí)行,,退出虛擬擬機返回操操作系統(tǒng),,并在標(biāo)準(zhǔn)準(zhǔn)輸出上打打印相關(guān)的的異常信息息。在另一種完完全相反的的情況下,,假設(shè)try塊中所所有語句的的執(zhí)行都沒沒有引發(fā)異異常,則所所有的catch塊塊都會被忽忽略而不予予執(zhí)行。上一頁下一頁返回5.3異常常的處理在設(shè)計catch塊塊處理不同同的異常時時,一般應(yīng)應(yīng)注意如下下問題:(1)catch塊塊中的語句句應(yīng)根據(jù)異異常的不同同執(zhí)行不同同的操作,,比較通用用的操作時時打印異常常和錯誤的的相關(guān)信息息,包括異異常名稱、、產(chǎn)生異常常的方法名名等。(2)由于于異常對象象與catch塊的的匹配是按按照catch塊的的先后排列列順序進行行的,所以以在處理多多異常時應(yīng)應(yīng)注意認(rèn)真真設(shè)計各catch塊的排列列順序。一一般地,處處理較具體體的較常見見的異常的的catch塊應(yīng)放放在前面,,而可以與與多種異常常相匹配的的catch塊應(yīng)放放在較后的的位置。上一頁下一頁返回5.3異常常的處理例如,對例例5-1中中的異常,,可以這樣樣處理:Try{…}catch(FileNotFoundExceptione){System.out.println(e);System.out.println(“massage:””+e.getMessage());e.printStackTrace(System.out);}catch{IOExceptionSystem.out.println(e);}上一頁下一頁返回5.3異常常的處理這里使用了了兩個catch語語句分別對對try代代碼塊中可可能出現(xiàn)的的兩個異常常事件進行行處理。如如果要打開開的文件““text”不存在在,程序運運行時就會會顯示下面面的信息::Java.io.FileNotFoundException:textMassage:textJava.io.FileNotFoundException:textAtjava.io.FilelnputStream.<init>(FilelnputStream.java)AtExceptionDemol.main(ExceptionDemol.java:7)上一頁下一頁返回5.3異常常的處理IOException是FileNotFoundException的的父類,從從程序的執(zhí)執(zhí)行結(jié)果可可以看到,,捕獲IOException對象的的代碼塊并并沒有被執(zhí)執(zhí)行。這是是因為當(dāng)運運行時系統(tǒng)統(tǒng)查找處理理異常的代代碼時,首首先從調(diào)用用堆棧的最最頂端開始始,也就是是從生成異異常對象的的方法開始始(例中為為FileInputStream的構(gòu)造造方法)。。由于FileInputStream的構(gòu)造造方法中沒沒有處理異異常的catch語語句,運行行時系統(tǒng)沿沿調(diào)用棧向向后回朔進進入方法main(),方法法main()中有有兩個catch語語句,運行行時系統(tǒng)把把異常對象象行的類型型依次和每每個catch語句句的參數(shù)類類型進行比比較,如果果類型相匹匹配,則把把該異常交交給這個catch代碼塊。。這里,匹匹配是指參參數(shù)類型與與異常對象象的類型完完全相同,,或者為其其父類。因因此第一個個catch塊被執(zhí)執(zhí)行。捕獲異常的的順序是和和不同catch語語句的順序序相關(guān)的,,如果在上上例中把兩兩個catch語句句的次序換換一下,則則在編譯時時會出現(xiàn)下下面的信息息:上一頁下一頁返回5.3異常常的處理ExceptionDemol.java:15:catchnotreached.}catch(FileNotFoundExceptione){^1error由于第一個個catch語句首首先得到匹匹配,第二二個catch語句句將不會被被執(zhí)行。因因此,在安安排catch語句句的順序時時,首先應(yīng)應(yīng)該捕獲最最特殊的異異常,然后后再逐漸一一般化。同同時也看到到,如果catch語句所捕捕獲的異常常類型不是是一個“終終極”類型型(即它有有子類),,則一個catch語句可以以同時捕獲獲多種異常常。如例中中的Catch(IOExceptione){…}上一頁下一頁返回5.3異常常的處理除了可以捕捕獲FileNotFoundException異常對對象以外,,還可以捕捕獲EOFException異常對對象,只要要他們是IOException類的的子類即可可。但通常在指指定所捕獲獲的異常類類型時,應(yīng)應(yīng)避免選擇擇最一般的的類型(如如Exception)。否否則,當(dāng)異異常事件發(fā)發(fā)生時,程程序中不能能確切判斷斷異常的具具體類型并并作出相應(yīng)應(yīng)處理以從從錯誤中恢恢復(fù)。[例5-5]多捕捕獲異常的的不同情況況。Importjava.io.*;ClassExceptionDemo{PublicStaticVoidmain(Stringargs[])ThrowsIOException{FileInputStreamfis=null;上一頁下一頁返回5.3異常常的處理Try{System.out.printIn(“firstargumentis““+args[0]);Fis=nesFileInputStream(“text”);System.out.printIn(“contentoftextis:”);Intb:Whine((b=fis.Read())!=-1){System.out.print((char)b);}}catch(Exceptione){//蔣蔣截獲所有有異常對象象,使后面面的catch塊不不能執(zhí)行,,需刪除System.out.printIn(e);上一頁下一頁返回5.3異常常的處理}catch(FileNotFoundExceptione){System.out.printIn(e);}catch(IOExceptione){System.out.printIn(e);}catch(IndexOutOfBoundExceptione){System.out.printIn(e);}finally{上一頁頁下一頁頁返回5.3異常常的處處理If(fis!=null){System.out.printIn(““closingFileInputStream……”);Fis.close();}else{System.out.printIn(FileInputStreamnotopen””);}}}}上一頁頁下一頁頁返回5.3異常常的處處理第一種種情況況,由由于所所有的的異常常都是是Exception類類的子子類,,這個個catch塊塊就可可以與與所有有的異異常對對象匹匹配,,排在在他后后面的的catch塊塊將永永遠不不被使使用。。正確確的方方法是是將以以Exception為為參數(shù)數(shù)的catch塊放放在最最后的的位置置。如如果去去掉以以Exception為為參數(shù)數(shù)的catch塊則則執(zhí)行行結(jié)果果為下下面幾幾種情情況。。(在在實際際運行行該例例題時時,應(yīng)應(yīng)將這這種情情況去去掉?。。┑谝环N種情況況,要要打開開的文文件””text”不不存在在,程程序運運行時時回生生成FileNotFoundException類類的的實例例,運運行時時系統(tǒng)統(tǒng)把它它交給給第一一個catch塊處處理,,最后后執(zhí)行行finally語語句,,運行行結(jié)果果如下下:上一頁頁下一頁頁返回5.3異常常的處處理C:\>javaExceptionDemohiFirstargumentishiJava.io.FileNotFoundException:testFileINputStreamnotopen第三種種情況況,我我們創(chuàng)創(chuàng)建了了文件件”text””,但但是在在運行行程序序時不不給出出任何何參數(shù)數(shù),這這時會會生成成IndexOutOfBoundsException類類的異異常,,它是是運行行時異異常,,運行行時系系統(tǒng)把把它交交給第第三個個catch語語句,,最后后執(zhí)行行finally語語句,,運行行結(jié)果果如下下:上一頁頁下一頁頁返回5.3異常常的處處理C:\>javaExceptionDemoJava.Lang.ArrayINdexOutOfBoundsException()FileINputStreamnotopen第四種種情況況,程程序正正常執(zhí)執(zhí)行完完try代代碼塊塊后,,執(zhí)行行finally語語句,,運行行結(jié)果果如下下:C:\>javaExceptionDemohiFirstargumentishiContenoftextis:Letusbegintoknowjava,learnjavaandmasterjavaclosingFileInputStream……上一頁頁返回5.4異異常地地拋出出在Java程序序運行行時如如果出出現(xiàn)一一個可可識別別的錯錯誤,,就會會生成成一個個與該該錯誤誤相對對應(yīng)的的異常常類的的對象象,并并將其其傳遞遞給Java運運行系系統(tǒng),,這個個過程程被稱稱為異異常地地拋出出。根根據(jù)異異常類類的不不同,,拋出出異常常的方方法也也不同同。5.4.1系系統(tǒng)自自動拋拋出的的異常常在編譯譯例5-1程序序中,,程序序就會會指出出錯誤誤,自自動拋拋出對對應(yīng)的的異常常,在在屏幕幕上顯顯示::Java.io.FileNotFoundException,java.io.IOException表示該該程序序給定定的文文件名名未找找到以以及輸輸入、、輸出出異常常。對對于這這些異異常,,如果果程序序不進進行處處理了了,可可能會會帶來來意想想不到到的結(jié)結(jié)果,,因此此Java編譯譯器要要求程程序必必須拋拋出這這種異異常。。下一頁頁返回5.4異異常地地拋出出在例5-2的例例子中中,程程序運運行中中遇到到了錯錯誤,,系統(tǒng)統(tǒng)自動動拋出出對應(yīng)應(yīng)的異異常,,在屏屏幕上上顯示示:Java.lang.ArithmeticException由于該該程序序錯誤誤地以以0為為除數(shù)數(shù),運運行過過程中中就引引發(fā)算算數(shù)異異常ArithmeticException。同樣在在例5-3測試試異常常程序序中,,涉及及了四四個錯錯誤進進行測測試,,運行行后系系統(tǒng)自自動拋拋出了了對應(yīng)應(yīng)的四四個異異常類類的對對象。。以上異異常時時系統(tǒng)統(tǒng)預(yù)先先定義義好的的類,,對應(yīng)應(yīng)系統(tǒng)統(tǒng)是可可識別別的錯錯誤,,所以以Java編譯譯器或或Java虛擬擬機遇遇到這這樣的的錯誤誤就會會自動動中止止程序序的執(zhí)執(zhí)行流流程,,拋出出對應(yīng)應(yīng)的異異常。。所有的的系統(tǒng)統(tǒng)定義義的編編譯和和運行行異常常都可可以由由系統(tǒng)統(tǒng)自動動拋出出,稱稱標(biāo)準(zhǔn)準(zhǔn)異常常,并并且Java強強烈的的要求求應(yīng)用用程序序進行行完整整的異異常處處理,,給用用戶友友好的的提示示,或或者修修正后后使程程序繼繼續(xù)執(zhí)執(zhí)行。。上一頁頁下一頁頁返回5.4異異常地地拋出出5.4.2語語句拋拋出的的異常常用戶程程序自自定義義的異異常和和應(yīng)用用程序序特定定的異異常,,是不不可能能依靠靠系統(tǒng)統(tǒng)聲明明拋出出異常常和自自動拋拋出異異常,,而必必須借借助于于throws和throw語句句來定定義拋拋出異異常,,并且且確定定何種種情況況算是是產(chǎn)生生了此此種異異常對對應(yīng)的的錯誤誤和拋拋出這這個異異常類類的新新對象象。用throws聲明明拋出出異常常和用用throw語語句拋拋出異異常對對象的的語法法格式式為::[格格式式]修修飾飾符符返返回回類類型型方方法法名名((參參數(shù)數(shù)列列表表))throws異異常常類類1,,異異常常類類2,,…………{………Throw異異常常類類名名;;………}上一一頁頁下一一頁頁返回回5.4異異常常地地拋拋出出[說說明明](1))一一般般這這種種怕怕拋拋出出異異常常的的語語句句應(yīng)應(yīng)該該被被定定義義為為在在滿滿足足一一定定條條件件時時執(zhí)執(zhí)行行,,如如把把throw語語句句放放在在if分分支支中中,,只只有有當(dāng)當(dāng)if條條件件得得到到滿滿足足,,即即用用戶戶定定義義的的邏邏輯輯錯錯誤誤發(fā)發(fā)生生時時才才執(zhí)執(zhí)行行。。(2))自自定定義義被被拋拋出出的的異異常常必必須須是是Throwable類類或或其其子子類類的的實實例例。。(3))含含有有throw語語句句的的方方法法應(yīng)應(yīng)該該在在方方法法頭頭定定義義中中增增加加如如下下的的部部分分::Throws聲聲明明拋拋出出異異常常類類名名列列表表即將將幾幾個個throw語語句句可可能能拋拋出出的的異異常常,,均均集集中中列列入入throws中中,,并并用用逗逗號號分分割割開開來來。。聲聲明明拋拋出出異異常常類類名名列列表表,,就就使使得得異異常常對對象象可可以以依依次次向向后后查查找找,,直直到到有有合合適適的的方方法法捕捕獲獲他他為為止止。。實實例例見見下下面面““5.5應(yīng)應(yīng)用用舉舉例例””一一節(jié)節(jié)。。在系統(tǒng)不能識識別的創(chuàng)建用用戶自定義的的異常時,需需要編程者在在程序中合適適位置創(chuàng)建自自定義異常的的對象,并利利用throw語句將這這個新異常對對象拋出。上一頁返回5.5應(yīng)用舉舉例本例演示了如如何對異常條條件生成用戶戶定義的異常常類層,和如如何用這些用用戶定義的異異常類編寫程程序來處理異異常條件。例例子的第一部部分構(gòu)造了一一個報告年齡齡相關(guān)異常的的異常類層,,如圖5-2所示。這個層次的根根為AgeException類。。它有一個數(shù)數(shù)據(jù)成員Age,用于防防治導(dǎo)致異常常發(fā)生的年齡齡。它有兩個個子類:類OutOfAgeLimtException用了對于特特定任務(wù)年齡齡太小或太老老的情況,而而類IllegalAgeFormatException用于年齡齡在合法范圍圍以外或格式式有錯誤的情情況。前一個個類用數(shù)據(jù)成成員agelinmit來設(shè)置置可接受的年年齡極限,定定義這些類的的程序如下::下一頁返回5.5應(yīng)用舉舉例Importjava.io.*;ClassAgeExceptionextendsException{Intage;AgeException(){Super();}AgeException(Stringmessage){Super(message);}}上一頁下一頁返回5.5應(yīng)用舉舉例ClassOutOfAgeLimtExceptionextendsAgeException{IntageLimit;OutOfAgeLimtExceptionextendsAgeException{Super(message);}OutOfAgeLimtException(intageLimit,Stringmessage){Super(message);This.ageLimit=ageLimit;}}上一頁下一頁返回5.5應(yīng)用舉舉例ClassTooYoungExceptionextendsOutOfAgeLimtException{TooYoungException(){Super(“tooyoung”);}TooYoungException(intage,intageLimit,Stringmessage){Super(ageLimit,”Youaretooyoungto”+message+”.””);This.age=age;}}上一頁下一頁返回5.5應(yīng)用舉舉例ClassTooOldExceptionextends
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 商業(yè)裝修合同糾紛解決方案范文
- 金融行業(yè)資產(chǎn)評估服務(wù)合同
- 音像出版合同
- 商品房買賣怎么寫協(xié)議書(范文15篇)
- 個人住宅用戶新裝寬帶業(yè)務(wù)包年優(yōu)惠協(xié)議(臺州)5篇
- 2025年權(quán)利質(zhì)押合同8篇
- 2025買二手房草簽合同7篇
- 【房屋買賣合同范本】房屋買賣合同5篇
- 聽力遠程教育研究-全面剖析
- 借條實際上是一份簡化的借款合同8篇
- 2025年河南農(nóng)業(yè)職業(yè)學(xué)院單招職業(yè)技能測試題庫及參考答案
- 人教PEP版英語五年級下冊全冊教案
- 2025年個體古董借款質(zhì)押合同示范本
- 交管12123駕駛證減分學(xué)法題庫(部分)(圖文版)
- 油氣藏產(chǎn)能預(yù)測模型-深度研究
- 2025年四川成都市蒲江鄉(xiāng)村建設(shè)發(fā)展集團有限公司招聘筆試參考題庫附帶答案詳解
- 2024版房產(chǎn)經(jīng)紀(jì)人無底薪勞動協(xié)議
- 2025年上半年度交通運輸部南海航海保障中心公開招聘126人工作人員易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年上海煙草集團上海新型煙草制品研究院限公司招聘8人高頻重點提升(共500題)附帶答案詳解
- 2025年中郵證券有限責(zé)任公司招聘筆試參考題庫含答案解析
- 社戒社康培訓(xùn)
評論
0/150
提交評論