第7講 異常課件_第1頁
第7講 異常課件_第2頁
第7講 異常課件_第3頁
第7講 異常課件_第4頁
第7講 異常課件_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第7講異常處理第7講異常為什么要異常處理?對于任何語言的程序設計而言,錯誤的發(fā)生總是不可避免的為了加強程序的健壯性,程序設計時,必須充分考慮錯誤發(fā)生的可能性,并建立相應的處理機制。

第7講異常什么是異常?異常(Exception)又稱為例外,是指在程序運行過程中發(fā)生的非正常事件,這些事件的發(fā)生會影響程序的正常執(zhí)行。如:進行數(shù)學中“無意義”的運算,例如除數(shù)為零、對負數(shù)求對數(shù)平方根等對數(shù)組進行操作時,超出了數(shù)組的最大下標程序所需進行的I/O操作不能正常執(zhí)行,如所需訪問的文件不存在內(nèi)存耗盡無法進行類的實例化JVM崩潰第7講異常異常對象在Java語言中,我們用異常對象來表示不同的異常。所謂Java異常對象就是一個存放著相關錯誤信息的對象,如果方法運行時產(chǎn)生了異常,該方法就可以拋出一個異常對象為了表示不同種類的異常,Java語言中定義了許多異常類。第7講異常方法的調(diào)用堆棧main()methodA()methodB()methodC()調(diào)用Java程序在執(zhí)行的過程中,形成了一個先進后出的調(diào)用堆棧,各方法之間依照調(diào)用先后的不同,由先至后的進入調(diào)用堆棧,堆棧的最上層即是當前被調(diào)用執(zhí)行的方法。該方法執(zhí)行完畢后,會將處理器控制權交還給調(diào)用他的方法,依此類推。第7講異常方法調(diào)用堆棧中異常對象的傳遞

當某一方法中的一個語句拋出一個異常時,如果該方法中沒有處理該異常的語句,那么該方法就會中止執(zhí)行,并將這個異常傳遞給堆棧中的下一層方法,直到某一方法中含有處理該異常的語句為止。如果該異常被傳遞至主方法,而主方法中仍然沒有處理該異常的語句,則異常將會被拋至JVM,程序中斷。main()methodA()methodB()methodC()調(diào)用傳遞第7講異常例程publicclassExampleOfException{String[]lines={"Thefirstline","Thesecondline","Thelastline"};publicstaticvoidmain(String[]args){ExampleOfExceptioneoe=newExampleOfException();eoe.methodA();

System.out.println("Programfinished.");}voidmethodA(){methodB();}voidmethodB(){methodC();}voidmethodC(){

for(inti=0;i<4;i++)System.out.println(lines[i]);}}

ThefirstlineThesecondlineThelastlineExceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException:3atExampleOfException.methodC(ExampleOfException.java:16)atExampleOfException.methodB(ExampleOfException.java:12)atExampleOfException.methodA(ExampleOfException.java:9)atExampleOfException.main(ExampleOfException.java:6)第7講異常Java中的異常類在Java語言中,任何的異常對象都是Throwable類的直接子類或間接子類的實例。Java的類庫已經(jīng)提供了一些常見的異常類,如果這些異常類不能夠滿足要求,用戶也可以創(chuàng)建自己的異常類。第7講異常Exception類

Exception的子類表示了不同類型的異常,例如RuntimeException表示運行時異常,而IOException表示I/O問題引起的異常。這些子類也可以再被繼承以對不同類型的異常進行細分,如RuntimeException還可細分為NullPointerException、ArithmeticException等;IOException還可細分為、EOFException等。第7講異常常見的異常類ArithmeticExceptionArrayIndexOutOfBandsExceptionIOExceptionNullPointerExceptionNumberFormatException第7講異常Error類

Error類表示Java運行時產(chǎn)生的系統(tǒng)內(nèi)部錯誤或資源耗盡等嚴重錯誤。這種錯誤通常是程序無法控制和解決的,如果發(fā)生這種錯誤,通常的做法是通知用戶并中止程序的執(zhí)行。第7講異常常見的錯誤類NoClassDefFoundErrorOutOfMemoryErrorVirtualMachineError第7講異常必檢異常與非必檢異常RuntimeException類及其子類被稱為“運行時異?!币话惆l(fā)生在JRE內(nèi)部也稱“非必檢異?!比鏝ullPointerException其他異常被成為“非運行時異常”一般發(fā)生在JRE外部也稱“必檢異?!比鏘OException第7講異常異常處理的一般步驟異常拋出異常捕獲異常處理第7講異常拋出異常方法中需要拋出異常時,可使用throw語句實現(xiàn),具體步驟應該是:選擇合適的異常類;創(chuàng)建該類的一個對象;使用throw語句拋出該對象。第7講異常拋出異常例如,某方法readFile()對文件進行讀操作,根據(jù)文件讀寫基本知識可知:當進行I/O操作時,可能會產(chǎn)生I/O異常。所以,在方法readFile中如果讀文件操作不成功,則應拋出I/O異常。如下列程序片斷所示:readFile()throwsIOException{…if(讀文件不成功) thrownewIOExcepion();}第7講異常拋出異常如果一個方法可能拋出多個必檢異常,那么必須在方法的聲明部分一一列出,多個異常間使用逗號進行分隔:

ClassMyClass{ …publicmyMethod(Strings)throwsIOException,ArrayIndexOutOfBandsException{…}…} 第7講異常拋出異常一個方法必須通過throws語句在方法的聲明部分說明它可能拋出而并未捕獲的所有的“必檢異?!?,如果沒有這么做,將不能通過編譯。值得注意的是:如果在子類中覆蓋了父類的某一方法,那么該子類方法不可以比被其覆蓋的父類方法拋出更多的異常(但可以更少)。所以,如果被覆蓋父類的方法沒有拋出任何的“必檢異?!?,那么子類方法絕不可能拋出“必檢異?!?。第7講異常拋出異常在下面的例子里,對于父類SuperClass而言,類SubClassA是正確的子類,而SubClassB則是錯誤的。classSuperClass{ publicsuperMethod()throwsEOFException{ … }}classSubClassAextendsSuperClass{ //正確

publicsuperMethod(){ … }}classSubClassBextendsSuperClass{ //錯誤

publicsuperMethod()throws{ … }}第7講異常異常的捕獲要捕獲一個異常,程序員只需要在程序中設置一個try/catch塊,其格式如下:

try{

拋出異常的代碼

}catch(某Exception類型e){

處理該異常類型的代碼

}catch(某Exception類型e){

處理該異常類型的代碼

}finally{

……

}第7講異常異常的捕獲當try塊中的某條代碼拋出異常時:首先,自該語句的下一條語句起的所有try塊中的剩余語句將被跳過不予執(zhí)行;其次,程序執(zhí)行catch子句進行異常捕獲,異常捕獲的目的是進行異常類型的匹配,并執(zhí)行與所拋出的異常類型相對應的catch子句中的異常處理代碼,類似于switch語句中的case,但不需寫break;最后執(zhí)行finally語句塊(finally語句塊可以缺省,但是一旦進行了定義則語句塊必須執(zhí)行)。第7講異常異常的捕獲需要注意的是:如果try塊中沒有任何的異常拋出,則所有的catch子句將會被跳過;如果try塊中所拋出的異常對象類型與所有的catch子句中的所聲明的異常類型都不匹配,則方法會立即中止,并將該異常對象繼續(xù)拋出,拋給該方法的調(diào)用者、調(diào)用者的調(diào)用者……,沿調(diào)用堆棧傳遞。第7講異常examplepublicclassExampleOfException{String[]lines={"Thefirstline","Thesecondline","Thelastline"};publicstaticvoidmain(String[]args){ExampleOfExceptioneoe=newExampleOfException();eoe.methodA();

System.out.println("Programfinished.");}...voidmethodC(){for(inti=0;i<4;i++){try{System.out.println(lines[i]);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println("Re-settingIndexValue");}}}}第7講異常example上面的例子中可能會產(chǎn)生數(shù)組越界異常,所以將其置于try塊中,并在catch子句中對ArrayIndexOutOfBoundsException類型的異常進行捕獲,并進行處理。如果try塊中可能拋出多個類型的異常,程序員可以使用多個catch子句對這些異常進行捕獲,每種異常類型對應一個單獨的catch子句。需要注意的是,這些catch子句是順序執(zhí)行的。這意味著,異常對象總是被第一個catch子句首先捕獲,如果類型不匹配,才會執(zhí)行下一個catch子句。讀者可以試著分析下面的程序片斷,看看有什么樣的問題存在。第7講異常問題Java運行系統(tǒng)從上到下分別對每個catch語句處理的例外類型進行檢測,直到類型匹配為止;catch語句的排列順序應該是從子類到父類try{…}catch(Exceptione){…}catch(IOExceptione){…}catch(ArrayIndexOutOfBoundsExceptione){…}第7講異常finally當一個方法的某條語句拋出異常后,該方法剩余的語句將無法繼續(xù)執(zhí)行。這種情況下,方法往往無法將其占用的資源進行釋放。解決方法:在每個catch子句的異常處理代碼中也加上資源釋放的代碼,但這種方法非常麻煩;Java語言的異常處理機制中提供了一個更好的方案-程序員可以使用finally子句來統(tǒng)一進行資源釋放之類的工作。第7講異常finallyfinally子句的一般格式:

try{

拋出異常的代碼

}catch(某Exception類型e){

處理該異常類型的代碼

}

…}catch(某Exception類型e){

處理該異常類型的代碼

}finally{

最后一定會被執(zhí)行的代碼

}第7講異常finally不論try塊中的代碼是否拋出異常及異常是否被捕獲,finally子句中的代碼一定會被執(zhí)行:如果try塊中沒有拋出任何異常,當try塊中的代碼執(zhí)行結(jié)束后,finally中的代碼將會被執(zhí)行;如果try塊中拋出了一個異常且該異常被catch正常捕獲,那么try塊中自拋出異常的代碼之后的所有代碼將會被跳過,程序接著執(zhí)行與拋出異常類型匹配的catch子句中的代碼,最后執(zhí)行finally子句中的代碼。如果try塊中拋出了一個不能被任何catch子句捕獲(匹配)的異常,try塊中剩下的代碼將會被跳過,程序接著執(zhí)行finally子句中的代碼,未被捕獲的異常對象繼續(xù)拋出,沿調(diào)用堆棧順序傳遞。第7講異常問題當調(diào)用上述方法m()時,try塊中包含方法的return語句,返回值為1。然而,實際調(diào)用該方法后產(chǎn)生的返回值為0。這是因為在方法實際返回并結(jié)束前,finally子句中的內(nèi)容無論如何要被執(zhí)行,所以finally子句中的return語句使得該方法最終實際返回值為0。publicintm(){try{ return1;}finally{ return0;}}第7講異常examplepublicclassTryCatchFinally{staticvoidProc(intsel){System.out.println("-----InSituation"+sel+"-----");try{if(sel==0){System.out.println("noExceptioncaught");return;}elseif(sel==1){inti=0;intj=4/i;}elseif(sel==2){intiArray[]=newint[4];iArray[10]=3;}第7講異常example

}catch(ArithmeticExceptione){System.out.println("Catch"+e);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println("Catch"+e.getMessage());}catch(Exceptione){System.out.println("Willnotbeexecuted");}finally{System.out.println("inProcfinally");}}

publicstaticvoidmain(Stringargs[]){Proc(0);Proc(1);Proc(2);}}程序運行結(jié)果:-----InSituation0-----noExceptioncaughtinProcfinally-----InSituation1-----Catchjava.lang.ArithmeticException:/byzeroinProcfinally-----InSituation2-----Catch10inProcfinally第7講異常聲明異常一個方法不處理它產(chǎn)生的異常,而是沿著調(diào)用堆棧向上傳遞,由調(diào)用它的方法來處理這些異常,則需要聲明異常。聲明異常的方法:returnTypemethodName([paramlist])throwsexceptionList例如:voidcompute(intx)throwsArithmeticException{

…}第7講異常examplepublicclassThrowsException1{staticvoidProc(intsel)throwsArrayIndexOutOfBoundsException{System.out.println("-----InSituation"+sel+"-----");if(sel==0){System.out.println("noExceptioncaught");return;}elseif(sel==1){intiArray[]=newint[4];iArray[10]=3;}}第7講異常example

publicstaticvoidmain(Stringargs[]){try{Proc(0);Proc(1);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println("Catch"+e);}finally{System.out.println("inProcfinally");}}}程序運行結(jié)果:-----InSituation0-----noExceptioncaught-----InSituation1-----Catchjava.lang.ArrayIndexOutOfBoundsException:10inProcfinally第7講異常創(chuàng)建自己的異常類Java語言中允許用戶定義自己的異常類,這些用戶自定義異常類必須是Throwable的直接子類或間接子類。根據(jù)Java異常類的繼承關系,用戶最好將自己的異常類定義為Exception的子類,而不要將其定義為RuntimeException的子類。因為對于RuntimeException的子類而言,即使調(diào)用者不進行處理,編譯程序也不會報錯。將自定義異常類定義為Exception的子類,可以確保調(diào)用者對其進行處理。第7講異常exampleclassMyExceptionextendsException{privateintdetail;MyException(inta){detail=a;}publicStringtoString(){return"MyException"+detail;}}

第7講異常examplepublicclassExceptionDemo{staticvoidcompute(inta)throwsMyException{System.out.println("calledcompute("+a+")");if(a>10)

thrownewMyException(a);System.out.println("normalexit");}publicstaticvoidmain(Stringargs[]){try{compute(1);compute(20);}catch(MyExceptione){System.out.println("Caught"+e);}}}程序運行結(jié)果:calledcompute(1)

normalexit

calledcompute(20)

CaughtMyException20第7講異常異常的優(yōu)點將錯誤處理代碼與“常規(guī)”代碼分離;條理清晰,便于分析和調(diào)試提高程序容錯性和健壯性將錯誤沿調(diào)用堆棧傳遞;可以由感興趣的方法來處理異常對錯誤類型進行分組和區(qū)分。第7講異常說明的問題方法也可以不對異常進行捕獲而直接將其拋出,并在方法聲明中進行說明,那么對方法產(chǎn)生的異常到底是應該直接進行捕獲還是應該將其進行傳遞呢?一般來說,對于方法的最終調(diào)用者而言,他必須捕獲并處理該方法拋出的異常。而對于拋出異常的方法而言,應該對方法可能產(chǎn)生的異常進行區(qū)分,盡量避免一些異常的產(chǎn)生,捕獲并處理那些你知道如何處理的異常,而對那些你不知道方法的調(diào)用者會如何處理的異常,最好將它們留給方法的調(diào)用者進行處理,這樣就會增加程序的靈活性。第7講異常說明的問題需要特別指出的是,雖然異常處理

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論