版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第六章異常處理本章主要內(nèi)容異常概述異常處理機(jī)制Checked異常和Runtime異常使用throw拋出異常Java的異常跟蹤棧異常處理規(guī)則程序中的錯誤可分為三類:編譯錯誤、邏輯錯誤和運(yùn)行時錯誤。
編譯錯誤是由于沒有遵循Java語言的語法規(guī)則而產(chǎn)生的,這種錯誤要在編譯階段排除,否則程序不可能運(yùn)行。
邏輯錯誤是指程序編譯正常,也能運(yùn)行,但結(jié)果不是人們所期待的。異常(Exception)又稱為例外,是指在程序運(yùn)行過程中發(fā)生的非正常事件,這些事件的發(fā)生會影響程序的正常執(zhí)行。①用戶輸入出錯②所需文件找不到③運(yùn)行時磁盤空間不夠④內(nèi)存不夠
⑤算術(shù)運(yùn)算錯(數(shù)的溢出,被零除…)⑥數(shù)組下標(biāo)越界......什么是異常?異常對象在Java語言中,我們用異常對象來表示不同的異常。所謂Java異常對象就是一個存放著相關(guān)錯誤信息的對象,如果方法運(yùn)行時產(chǎn)生了異常,該方法就可以拋出一個異常對象為了表示不同種類的異常,Java語言中定義了許多異常類。為什么要處理異常?異常處理機(jī)制是JAVA語言的重要特征之一。通過異常處理機(jī)制可防止程序執(zhí)行期間因出現(xiàn)錯誤而造成不可預(yù)料的結(jié)果。一個好的應(yīng)用程序,除了具備用戶要求的功能外,還要求能預(yù)見程序執(zhí)行過程中可能產(chǎn)生的各種異常,并把處理異常的功能包括在用戶程序中。在Java程序運(yùn)行過程中,產(chǎn)生的異常通常有三種類型:一是JAVA虛擬機(jī)由于某些內(nèi)部錯誤產(chǎn)生的異常,這類異常不在用戶程序的控制之內(nèi),也不需要用戶處理這類異常;二是標(biāo)準(zhǔn)異常類,由java系統(tǒng)預(yù)先定義好的。這類異常是由程序代碼中的錯誤而產(chǎn)生的,如:以零為除數(shù)的除法,訪問數(shù)組下標(biāo)范圍以外的數(shù)組元素,訪問空對象內(nèi)的信息,這是需要用戶程序處理的異常。三是根據(jù)需要在用戶程序中自定義的一些異常類。異常的類型Java中所有的異常都是用類表示的,在JAVA中預(yù)定義了很多異常類,每個代表了一種類型的運(yùn)行錯誤。當(dāng)程序發(fā)生異常時,會生成某個異常類的對象。Java解釋器可以監(jiān)視程序中發(fā)生的異常,如果程序中產(chǎn)生的異常與系統(tǒng)中預(yù)定義某個異常類相對應(yīng),系統(tǒng)就自動產(chǎn)生一個該異常類的對象,就可以用相應(yīng)的機(jī)制處理異常,確保程序能夠安全正常地繼續(xù)運(yùn)行。異常對象中含有這種運(yùn)行錯誤的信息和異常發(fā)生時程序的運(yùn)行狀態(tài)。Java異常處理的特點(diǎn)Java中標(biāo)準(zhǔn)異常類的層次結(jié)構(gòu)
針對各種類型的異常,Java定義了許多標(biāo)準(zhǔn)異常類,所有的Java異常類都是系統(tǒng)類庫中的Exception類的子類,它們分布在java.lang、java.io、java.util和包中。每個異常類對應(yīng)一種特定的運(yùn)行錯誤,各個異常類采用繼承的方式進(jìn)行組織。異常類的層次結(jié)構(gòu)圖如下圖所示:在Java語言中,任何的異常對象都是Throwable類的直接子類或間接子類的實(shí)例。Java的類庫已經(jīng)提供了一些常見的異常類,如果這些異常類不能夠滿足要求,用戶也可以創(chuàng)建自己的異常類。Java中異常類的層次結(jié)構(gòu)Throwable類有兩個直接子類:Error(致命錯誤)和Exception(異常)。Error類型的異常與JAVA虛擬機(jī)本身發(fā)生的錯誤有關(guān),這類異常由java直接處理,用戶程序一般不能太做什么,只能等待系統(tǒng)通知用戶關(guān)閉程序。用戶程序產(chǎn)生的錯誤由Exception的子類表示。用戶程序應(yīng)該處理這類異常。1、Throwable類該類屬于Java.lang包,是所有異常類的父類.在Throwable類中定義了描述異常發(fā)生的位置和所有異常類共同需要的內(nèi)容.
publicThrowable(Stringmessage)以message的內(nèi)容作為錯誤信息串創(chuàng)建Throwable對象,同時調(diào)用該對象的另一方法fillInStackTrace。publicThrowable()以null作為錯誤信息串內(nèi)容創(chuàng)建Throwable對象,同時調(diào)用該對象的另一方法fillInStackTrace記錄異常發(fā)生的位置。Throwable類的主要成員函數(shù)publicStringgetMessage()如果創(chuàng)建當(dāng)前對象時以message的內(nèi)容作為錯誤信息串,本方法返回串變量message的內(nèi)容;若創(chuàng)建當(dāng)前對象時未使用參數(shù)則返回null。publicStringtoString()
若當(dāng)前對象包含錯誤信息,本方法返回的字符串由三部分組成:當(dāng)前對象的類名,一個冒號和一個空格,錯誤信息的字符串;若當(dāng)前對象未包含錯誤信息則僅返回當(dāng)前對象的類名。publicvoidprintStackTrace()將跟蹤棧中的信息輸出,輸出的第一行是當(dāng)前對象toString()的返回值,其余各行是跟蹤棧中的信息。publicTrowablefillInStackTrace()將當(dāng)前異常對象的發(fā)生位置(類、方法和所在文件的行號)記錄到跟蹤棧對象中。Error類是Throwable類的子類,由系統(tǒng)保留,用戶不能使用。也就是說,Error類型的錯誤不允許用戶插手處理,由Java系統(tǒng)自行處理。Error類描述系統(tǒng)錯誤:如將字節(jié)碼裝入內(nèi)存的過程中和對字節(jié)碼進(jìn)行檢查的過程中遇到的問題、java的內(nèi)部錯誤、資源耗盡的情況。這類異常由java直接處理,用戶程序不要理會這類異常。2、Error類
Exception類是Throwable類的子類,用戶程序中可以直接使用Exception類處理Exception類型的異常。Exception類不僅繼承了Throwable類的方法,同時定義以下兩個構(gòu)造函數(shù):
publicException()publicException(Strings)說明:字符串s用來接收傳入的字符串信息,該信息通常是對錯誤的描述。3、Exception類必檢異常與非必檢異常RuntimeException類及其子類被稱為“運(yùn)行時異常”一般發(fā)生在JRE內(nèi)部也稱“非必檢異?!比鏝ullPointerException其他異常被成為“非運(yùn)行時異?!币话惆l(fā)生在JRE外部也稱“必檢異常”如IOException異常程序舉例://java直接處理運(yùn)行時異常classTestSystemException{publicstaticvoidmain(String[]args){int
num[]=newint[2];for(inti=1;i<3;i++){num[i]=i;System.out.println(“num[”+i+”]=”+i);}}}該程序產(chǎn)生的輸出見程序的運(yùn)行.Java對異常的處理涉及兩方面的內(nèi)容:一是拋出(throw)異常二是捕捉(catch)異常如果程序在運(yùn)行過程中出現(xiàn)了運(yùn)行錯誤,并且產(chǎn)生的異常與系統(tǒng)中預(yù)定義某個異常類相對應(yīng),系統(tǒng)就自動產(chǎn)生一個該異常類的對象,這個過程稱為拋出(throw)異常。當(dāng)有異常對象拋出時,將在程序中尋找處理這個異常的代碼,如果找到處理代碼,則把異常對象交給該段代碼進(jìn)行處理,這個過程稱為捕捉(catch)異常。如果程序中沒有給出處理異常的代碼,則把異常交給Java運(yùn)行系統(tǒng)默認(rèn)的異常處理代碼進(jìn)行處理。默認(rèn)的處理方式是:首先顯示描述異常信息的字符串,然后終止程序的運(yùn)行。
異常的處理機(jī)制異常的拋出(throw)拋出異常有兩種方式:由系統(tǒng)自動拋出和利用拋出語句拋出。1由系統(tǒng)自動拋出異常在程序運(yùn)行過程中,如果出現(xiàn)了可被Java運(yùn)行系統(tǒng)識別的錯誤,系統(tǒng)會自動產(chǎn)生與該錯誤相對應(yīng)的異常類的對象,即自動拋出。例如上例。2人為異常拋出兩種方式:①在方法頭寫出需要拋出的異常(利用throws語句)②在方法體內(nèi)拋出異常(利用throw語句)Throws語句拋出異常格式
修飾符返回值類型方法名([形參表])throws異常類名1,異常類名2,……{……}說明:在執(zhí)行該方法的過程中,如果出現(xiàn)了由throws列出的異常,則可以拋出異常,并在程序中尋找處理這個異常的代碼;如果程序中沒有給出處理異常的代碼,則把異常交給Java運(yùn)行系統(tǒng)默認(rèn)的異常處理代碼進(jìn)行處理。Throws語句舉例classThrows_Exp{publicstaticvoidmain(String[]args)throwsArithmeticException,ArrayIndexOutOfBoundsException{inta=4,b=0,c[]={1,2,3,4,5};System.out.println(a/b);System.out.println(c[a+1]);System.out.println(“end”); }}Throw語句拋出異常
如果需要在方法內(nèi)某個位置拋出異常,可以使用Throw語句,通常將Throw語句和if語句配合使用。格式:①throw異常類對象名②throw(new異常類名());說明:
執(zhí)行throw語句時,程序終止執(zhí)行后面的語句,在程序中尋找處理異常的代碼;如果程序中沒有給出處理代碼,則把異常交給Java運(yùn)行系統(tǒng)處理。Throw語句舉例1classThrow_Exp1{publicstaticvoidmain(String[]args){ArithmeticExceptione=newArithmeticException();inta=4,b=0;System.out.println(“BeforeArithmeticException”);if(b==0)throwe;System.out.println(a/b); }}
Throw語句舉例2classThrow_Exp2{publicstaticvoidmain(String[]args){inta=5,c[]={1,2,3,4,5};System.out.println(“BeforethrowArrayIndexOutOfBoundsException”);if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println(“AfterthrowArrayIndexOutOfBoundsException”); }}Throw語句舉例3classThrow_Exp3{publicstaticvoidmain(String[]args){inta=5,b=0,c[]={1,2,3,4,5};System.out.println(“Beforethrow”);if(b==0)throw(newArithmeticException());System.out.println(a/b);if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println(a/b);}}
捕捉異常在前面給出的例子中,由于程序中都沒有給出處理異常的代碼,因此拋出的異常都被Java運(yùn)行系統(tǒng)捕捉,由Java運(yùn)行系統(tǒng)進(jìn)行相應(yīng)處理。一般來說,在設(shè)計程序過程中,如果能夠預(yù)測程序中可能發(fā)生的異常,則應(yīng)在程序中給出處理代碼。而不交給Java運(yùn)行系統(tǒng)處理,對于程序中那些不能預(yù)測的異常,可交給Java運(yùn)行系統(tǒng)處理。要由程序自己捕捉和處理異常,需要建立try-catch-finally語句塊。try-catch語句塊格式:try{//在此區(qū)域內(nèi)或能發(fā)生異常;}catch(異常類1e1){//處理異常1;} …catch(異常類nen){//處理異常n;}[finally{//不論異常是否發(fā)生,都要執(zhí)行的部分;}]被監(jiān)視的塊該catch子句能夠捕捉和處理的異常類型(1)將可能發(fā)生異常的程序代碼放置在try程序塊中。如果該塊內(nèi)的代碼出現(xiàn)了異常,系統(tǒng)將終止try塊代碼的執(zhí)行,自動跳轉(zhuǎn)到所發(fā)生的異常類對應(yīng)的catch塊中,執(zhí)行該塊中的代碼。如果程序運(yùn)行正常,后面的各catch塊不起任何作用。(2)finally塊是個可選項(xiàng),無論異常是否發(fā)生,finally塊的代碼必定執(zhí)行。通常把對各種異常共同處理部分放在finally塊中,如輸出統(tǒng)一信息、釋放資源、清理內(nèi)存、關(guān)閉已打開的文件等。(3)一個try塊可以對應(yīng)多個catch塊,用于對多個異常類進(jìn)行捕獲。但最多只能選中一個執(zhí)行。(4)異常對象與catch塊中聲明的實(shí)例的匹配原則: 異常對象是catch塊中聲明的異常類的實(shí)例;
異常對象是catch塊中聲明的異常類的某一子類的實(shí)例; Try-catch-finally結(jié)構(gòu)說明:try-catch-finally執(zhí)行過程當(dāng)try塊中的某條代碼拋出異常時:首先,自該語句的下一條語句起的所有try塊中的剩余語句將被跳過不予執(zhí)行;其次,程序執(zhí)行catch子句進(jìn)行異常捕獲,異常捕獲的目的是進(jìn)行異常類型的匹配,并執(zhí)行與所拋出的異常類型相對應(yīng)的catch子句中的異常處理代碼。需要注意的是:如果try塊中沒有任何的異常拋出,則所有的catch子句將會被跳過;如果try塊中所拋出的異常對象類型與所有的catch子句中的所聲明的異常類型都不匹配,則方法會立即中止,并將該異常對象繼續(xù)拋出,沿調(diào)用堆棧傳遞。try-catch-finally執(zhí)行過程當(dāng)一個方法的某條語句拋出異常后,該方法剩余的語句將無法繼續(xù)執(zhí)行。這種情況下,方法往往無法將其占用的資源進(jìn)行釋放。解決方法:在每個catch子句的異常處理代碼中也加上資源釋放的代碼,但這種方法非常麻煩;Java語言的異常處理機(jī)制中提供了一個更好的方案-程序員可以使用finally子句來統(tǒng)一進(jìn)行資源釋放之類的工作。try-catch-finally執(zhí)行過程不論try塊中的代碼是否拋出異常及異常是否被捕獲,finally子句中的代碼一定會被執(zhí)行:如果try塊中沒有拋出任何異常,當(dāng)try塊中的代碼執(zhí)行結(jié)束后,finally中的代碼將會被執(zhí)行;如果try塊中拋出了一個異常且該異常被catch正常捕獲,那么try塊中自拋出異常的代碼之后的所有代碼將會被跳過,程序接著執(zhí)行與拋出異常類型匹配的catch子句中的代碼,最后執(zhí)行finally子句中的代碼。如果try塊中拋出了一個不能被任何catch子句捕獲(匹配)的異常,try塊中剩下的代碼將會被跳過,程序接著執(zhí)行finally子句中的代碼,未被捕獲的異常對象繼續(xù)拋出,沿調(diào)用堆棧順序傳遞。try-catch-finally執(zhí)行過程try-catch-finally語句舉例1classTry_Catch_Exp1{publicstaticvoidmain(String[]args){intd=0,a;
try{System.out.println("BeforethrowException");a=5/d;System.out.println("theExceptionisthrow,Thestatementis'trun");}
catch(ArithmeticExceptione){
System.out.println("處理算數(shù)異常的catch語句塊捕獲了異常!"); System.out.println("捕獲的異常為"+e);}
catch(ArrayIndexOutOfBoundsExceptione){System.out.println("處理數(shù)組下標(biāo)越異常的catch語句塊捕獲了異常!"); System.out.println("捕獲的異常為"+e);}
finally{System.out.println("這是所有catch塊的共有部分!");}System.out.println("try-catch-finally塊后面的語句");}}
try-catch-finally語句舉例2classTry_Catch_Exp2{publicstaticvoidmain(String[]args){inta=5,b=0,c[]={1,2,3,4,5};
try{ System.out.println("Beforethrow");if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println("Afterthrow");}
catch(ArrayIndexOutOfBoundsExceptione){System.out.println("處理數(shù)組下標(biāo)越異常的catch語句塊捕獲了異常!"); System.out.println("捕獲的異常為"+e);}
finally{System.out.println("這是所有catch塊的共有部分!");}System.out.println("try-catch-finally塊后面的語句");}}
try-catch-finally語句舉例3publicclassExampleOfException{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");}}}}example上面的例子中可能會產(chǎn)生數(shù)組越界異常,所以將其置于try塊中,并在catch子句中對ArrayIndexOutOfBoundsException類型的異常進(jìn)行捕獲,并進(jìn)行處理。如果try塊中可能拋出多個類型的異常,程序員可以使用多個catch子句對這些異常進(jìn)行捕獲,每種異常類型對應(yīng)一個單獨(dú)的catch子句。需要注意的是,這些catch子句是順序執(zhí)行的。這意味著,異常對象總是被第一個catch子句首先捕獲,如果類型不匹配,才會執(zhí)行下一個catch子句。讀者可以試著分析下面的程序片斷,看看有什么樣的問題存在。問題當(dāng)調(diào)用上述方法m()時,try塊中包含方法的return語句,返回值為1。然而,實(shí)際調(diào)用該方法后產(chǎn)生的返回值為0。這是因?yàn)樵诜椒▽?shí)際返回并結(jié)束前,finally子句中的內(nèi)容無論如何要被執(zhí)行,所以finally子句中的return語句使得該方法最終實(shí)際返回值為0。publicintm(){try{ return1;}finally{ return0;}}用戶自定義的異常類
盡管Java提供了很多異常類,但用戶還是可以根據(jù)需要定義自己的異常類,即創(chuàng)建自定義異常類。
說明:(1)用戶自定義的異常類必須是Throwable類或Exception類的子類。(2)自定義的異常類,一般只要聲明兩個構(gòu)造方法,一個是不用參數(shù)的,另一個以字符串為參數(shù)。作為構(gòu)造方法參數(shù)的字符串應(yīng)當(dāng)反映異常的信息。其一般形式為:class自定義異常類名extendsException{
異常類體;}用戶自定義的異常類格式:自定義異常類classMyExceptionextendsException{…}用戶定義的異常同樣要用try--catch捕獲,但必須由用戶自己拋出thrownewMyException().用戶自定義的異常類舉例:classException_exp{ publicstaticvoidmain(String[]args){ try{System.out.println("2+3="+add(2,3)); System.out.println("-8+10="+add(-8,10));} catch(Exceptione){System.out.println("Exceptionis"+e);}}staticintadd(intn,intm)throwsUserException{ if(n<0||m<0)thrownewUserException();returnn+m;}}
classUserExceptionextendsException{ UserException(){super("數(shù)據(jù)為負(fù)數(shù)");}}Java的異常跟蹤棧main()methodA()methodB()methodC()調(diào)用Java程序在執(zhí)行的過程中,形成了一個先進(jìn)后出的調(diào)用堆棧,各方法之間依照調(diào)用先后的不同,由先至后的進(jìn)入調(diào)用堆棧,堆棧的最上層即是當(dāng)前被調(diào)用執(zhí)行的方法。該方法執(zhí)行完畢后,會將處理器控制權(quán)交還給調(diào)用他的方法,依此類推。方法調(diào)用堆棧方法調(diào)用堆棧中異常對象的傳遞
當(dāng)某一方法中的一個語句拋出一個異常時,如果該方法中沒有處理該異常的語句,那么該方法就會中止執(zhí)行,并將這個異常傳遞給堆棧中的下一層方法,直到某一方法中含有處理該異常的語句為止。如果該異常被傳遞至主方法,而主方法中仍然沒有處理該異常的語句,則異常將會被拋至JVM,程序中斷。main()methodA()methodB()methodC()調(diào)用傳遞實(shí)例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]);}}
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《促織》教學(xué)設(shè)計(2篇)
- 辦公室文員實(shí)習(xí)自我鑒定范本7篇
- 冬季施工方案范文錦集九篇
- 2022中學(xué)教師辭職報告
- 員工辭職申請書模板8篇
- 2022年《張曉風(fēng)散文集》讀后感500字6篇
- 2024年化妝品企業(yè)與個人化妝品購銷合同3篇
- 個人述職報告-15篇
- 2024年中國竹花瓶市場調(diào)查研究報告
- 2025合伙人勞動合同參考范本
- GB/T 45008-2024稀土熱障涂層材料鋯酸釓鐿粉末
- 經(jīng)理與領(lǐng)導(dǎo)人員管理制度
- 全國第三屆職業(yè)技能大賽(數(shù)字孿生應(yīng)用技術(shù))選拔賽理論考試題庫(含答案)
- 2024年湖北省襄陽市高新區(qū)招聘46人歷年管理單位遴選500模擬題附帶答案詳解
- 物理實(shí)驗(yàn)知到智慧樹章節(jié)測試課后答案2024年秋沈陽理工大學(xué)
- 大國三農(nóng)II-農(nóng)業(yè)科技版智慧樹知到期末考試答案章節(jié)答案2024年中國農(nóng)業(yè)大學(xué)
- 2024年湛江市農(nóng)業(yè)發(fā)展集團(tuán)有限公司招聘筆試沖刺題(帶答案解析)
- (正式版)HGT 6313-2024 化工園區(qū)智慧化評價導(dǎo)則
- MOOC 創(chuàng)新思維與創(chuàng)業(yè)實(shí)驗(yàn)-東南大學(xué) 中國大學(xué)慕課答案
- JBT 1472-2023 泵用機(jī)械密封 (正式版)
- 二級公立醫(yī)院績效考核三級手術(shù)目錄(2020版)
評論
0/150
提交評論