




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第9章異常處理1本章主要內(nèi)容自定義異常類的設(shè)計4異常的定義與分類1try-catch-finally語句2拋出異常的方式329.1異常處理的基本概念異常(exception):在程序運行中由代碼產(chǎn)生的一種錯誤。在不支持異常處理的程序設(shè)計語言中,每一個運行錯誤必須由程序員手動控制(例如C語言)。Java語言:異常處理機制,將程序運行時的管理帶到面向?qū)ο蟮氖澜纭?9.1.1錯誤與異常按照錯誤的性質(zhì)分類:語法錯:是由于違反Java的語法規(guī)則而產(chǎn)生的錯誤,只要沒有編譯錯誤,才可生成字節(jié)碼。語義錯(運行錯):程序在語法上正確,但在語義上存在錯誤,如輸入數(shù)據(jù)格式錯、除數(shù)為0錯、給變量賦值超出其允許范圍等,這類錯誤只能在運行時發(fā)現(xiàn),有的還需進(jìn)行異常處理。邏輯錯:程序編譯通過,也可運行,但運行結(jié)果與預(yù)期不符。如由于循環(huán)條件不正確而沒有結(jié)果,循環(huán)次數(shù)不對等因素導(dǎo)致的計算結(jié)果不正確等。
只有憑借經(jīng)驗排查。4根據(jù)錯誤嚴(yán)重程度的不同將運行錯分類:錯誤:是指程序在執(zhí)行過程中所遇到的硬件或操作系統(tǒng)的錯誤,是致命的,需外界干預(yù)。如:內(nèi)存溢出、虛擬機錯等。異常:是指在硬件和操作系統(tǒng)正常時,程序遇到的運行錯。如數(shù)組越界、除數(shù)為0、操作數(shù)超出數(shù)據(jù)范圍等、異常不是致命的,但會導(dǎo)致程序非正常終止,異常處理機制使程序自身能夠捕獲和處理異常。59.1.2Java異常處理機制異常(類):是指程序在運行過程中發(fā)生由于算法考慮不周或軟件設(shè)計錯誤等導(dǎo)致的程序異常事件。拋出異常:在一個程序運行過程中,如果發(fā)生了異常事件,則產(chǎn)生一個代表該異常的對象,并把它提交給運行系統(tǒng)的過程稱為拋出(throw)異常。捕獲異常:異常拋出后,運行系統(tǒng)從生成異常對象的代碼開始,沿方法的調(diào)用棧逐層回溯查找,直到找到包含相應(yīng)異常處理的方法,并把異常對象提交給該方法為止,這個過程稱為捕獲(catch)異常。6異常對象可由應(yīng)用程序本身產(chǎn)生,也可能由JVM產(chǎn)生7Method1Method2Method3Read-filecallcallcalltry-catch
捕獲異常拋出異常throwsthrowsthrowsJava異常處理機制--執(zhí)行流程示意捕獲異??梢苑胖迷谏鲜鋈魏我粋€矩形之中。Java異常處理機制--異常類Java中定義了很多異常類,每個異常類代表一種運行錯誤,類中包含了該運行錯誤的信息和處理錯誤的方法等內(nèi)容。每當(dāng)Java程序運行過程中產(chǎn)生一個可識別的運行錯誤時,系統(tǒng)都會產(chǎn)生一個相應(yīng)的該異常類的對象。Java采取“拋出-捕獲”的方式,一旦一個異常對象產(chǎn)生了,系統(tǒng)就可以捕獲這些異常,并且有相應(yīng)的機制來處理它,確保不會產(chǎn)生死機、死循環(huán)或其他損害,從而保證了整個程序運行的安全性。這就是Java的異常處理機制。89.2異常處理類9
一個異常是由一個對象來代表的,所有的異常都直接或間接地繼承自Throwable類。在Java類庫的每個類包中都定義了異常類,這些異常類分成兩大類:Error類及Exception類,后者是Java程序中需要大量處理的。除了Java類庫所定義的異常類之外,用戶也可以通過繼承已有的異常類來定義自己的異常類,并在程序中使用(利用throw產(chǎn)生,throws聲明拋出,catch捕捉并處理)。10在“異常”類層次上的最上層有一個單獨的類叫做Throwable,它是java.lang包中的一個類。java.lang.Error:由Java虛擬機生成并拋出,包括動態(tài)鏈接失敗、虛擬機錯誤等,Java程序不做處理,必須交由操作系統(tǒng)處理。java.lang.Exception:供應(yīng)用程序使用的,它是用戶程序能夠捕捉到的異常情況。Java編譯器要求Java程序必須捕獲或聲明所有的非運行時異常。RuntimeException:Java虛擬機在運行時生成的異常,如被0除等系統(tǒng)錯誤、數(shù)組下標(biāo)超范圍等,其產(chǎn)生比較頻繁,處理麻煩,對程序可讀性和運行效率影響太大。由系統(tǒng)檢測,用戶可不做處理,系統(tǒng)將它們交給缺省的異常處理程序(當(dāng)然,必要時,用戶可對其處理)。1111異常類的層次結(jié)構(gòu)(參看圖9.1)ThrowableErrorExceptionRuntimeException缺省的異常處理程序由用戶捕獲或聲明并處理不做處理用戶自己產(chǎn)生的異常處理12一些常用的異常類Error(allinjava.lang)LinkageErrorThreadDeathVirtualMachineErrorInternalErrorOutOfMemoryErrorStackOverflowErrorUnknownErrorAWTError(injava.awt)…13Exception(injava.lang)ClassNotFoundExceptionCloneNotSupportedExceptionInterruptedException…RuntimeExceptionArithmeticExceptionClassCastExceptionInllegalArgumentExceptionInllegalThreadStateExceptionNumberFormatExceptionExceptionIOException(injava.io)CharConversionExceptionEOFExceptionFileNotFoundExceptionInterruptedIOException……14RuntimeExceptionInllegalMonitorStateExceptionInllegalStateExceptionIndexOutOfBoundsExceptionArrayIndexOutObBoundsExceptionStringIndexOutObBoundsExceptionNegativeArraySizeExceptionNullPointerExceptionSecurityException…EmptyStackException(injava.util)MissingResourceException(injava.util)NoSuchElementException(injava.util)…Exception構(gòu)造方法:publicException();publicException(Strings);Exception常用方法:publicStringtoString():該方法返回描述當(dāng)前Exception類信息的字符串。publicvoidprintStackTrace():該方法沒有返回值,它的功能是完成一個輸出操作,在當(dāng)前的標(biāo)準(zhǔn)輸出設(shè)備(一般是屏幕顯示器)上輸出當(dāng)前異常對象的堆棧使用軌跡,即程序先后調(diào)用并執(zhí)行了哪些對象或類的哪些方法,使得運行過程中產(chǎn)生了這個異常對象。通常是對該異常所對應(yīng)的錯誤描述。15Exception類常用方法程序?qū)﹀e誤與異常的處理方式有三種:一是程序不能處理的錯誤,交操作系統(tǒng)處理;二是程序應(yīng)避免而可以不去捕獲的運行時異常(RuntimeException);三是必須捕獲(使用try-catch-final)的非運行時異常。169.3處理異常異常類異常處理是通過try、catch、finally、throw、throws五個關(guān)鍵字來實現(xiàn)的。使用try-catch-finally語句捕獲和處理異常捕獲異常的意義:能讓程序來接收和處理異常對象,從而不影響其他語句的執(zhí)行。17使用try-catch-finally語句捕獲和處理異常捕獲異常:當(dāng)一個異常被拋出時,有專門的語句來接收這個被拋出的異常對象。當(dāng)一個異常類的對象被捕獲或接收后,用戶程序就會發(fā)生流程跳轉(zhuǎn),系統(tǒng)終止當(dāng)前的流轉(zhuǎn)而跳轉(zhuǎn)到專門的異常處理語句塊,或直接跳出當(dāng)前程序和JVM回到操作系統(tǒng)。18try-catch-finally語句語法格式:try
{
要檢查的語句序列
;//可能產(chǎn)生異常的語句}catch(異常類名形參對象名){
異常發(fā)生時的處理語句;//捕獲到某種異常對象時//進(jìn)行處理的代碼}finally{
異常發(fā)生時一定會運行的語句}19try-catch-finally語句捕獲和處理異常的順序:try塊中代碼拋出異常,若發(fā)生異常,則程序的運行便中斷,并拋出由“異常類”所產(chǎn)生的“對象”。同時,該代碼塊也指定了它后面的catch語句所捕獲的異常的范圍,每個catch塊都應(yīng)該與一個try語句塊相對應(yīng),這個try語句塊用來啟動Java的異常處理機制。catch用來指定需要捕獲的異常類型,捕獲到異常,然后流程自動跳過產(chǎn)生異常的語句后面的所有尚未執(zhí)行的語句,系統(tǒng)就直接跳到catch語句中,查看是否有匹配的異常類,若有就執(zhí)行相應(yīng)語句。20try-catch-finally語句捕獲和處理異常的順序:無論try程序塊是否捕獲到異常,或者捕獲到的異常是否與catch后面括號里的異常相同,最后一定會運行finally塊里的程序代碼;finally塊的代碼運行結(jié)束后,程序再轉(zhuǎn)到try-catch-finally塊之后的語句繼續(xù)運行。(
finally塊)若try塊中所有的語句都沒有引發(fā)異常,則所有的catch塊都會被忽略而不執(zhí)行。(
catch塊一定會被執(zhí)行嗎?)2122importjava.util.Scanner;publicclassDivide1{
publicstaticintdivide(inta1,inta2){
returna1/a2;//a2可能為0
}publicstaticvoidmain(Stringargs[]){Scannerscanner=newScanner(System.in);System.out.print("Pleaseenteranintegernumerator:");intone=scanner.nextInt();System.out.print("Pleaseenteranintegerdenominator:");inttwo=scanner.nextInt();intresult=divide(one,two);System.out.printf("\nResult:%d/%d=%d\n",one,two,result);}}//這個例子會產(chǎn)生錯誤,但是沒有處理機制,所以運行不穩(wěn)定。一個例子23importjava.util.*;publicclassDivideOk{publicstaticintdivide(inta1,inta2)throwsArithmeticException{
returna1/a2;
}publicstaticvoidmain(Stringargs[]){Scannerscanner=newScanner(System.in);booleancontinueLoop=true;
do{try{}catch(InputMismatchExceptioninputMismatchException){}catch(ArithmeticExceptionarithmeticException){}}while(continueLoop);}}//增加捕獲異常語句,能夠處理除數(shù)為零(a2為0)的程序增加異常捕獲語句24do{try{System.out.print(“請輸入被除數(shù):");intone=scanner.nextInt();System.out.print(“請輸入除數(shù):");inttwo=scanner.nextInt();intresult=divide(one,two);System.out.printf("\nResult:%d/%d=%d\n",one,two,result);continueLoop=false;//inputsuccessful;endlooping}catch(InputMismatchExceptioninputMismatchException){System.err.printf("\nException:%s\n",inputMismatchException);scanner.nextLine();//discardinputsousercantryagainSystem.out.println(“必須輸入整數(shù),請重新輸入:.\n");}catch(ArithmeticExceptionarithmeticException){System.err.printf("\nException:%s\n",arithmeticException);System.out.println(“除數(shù)為0,請重新輸入.\n");}}while(continueLoop);處理多個異常(多個catch塊)多異常處理通過一個try塊后面定義若干catch塊來實現(xiàn)的,每個catch塊用來接收和處理一種特定的異常對象。若try塊產(chǎn)生的異常對象被第一個catch塊所接收,則程序的流程將直接跳轉(zhuǎn)到這個catch語句塊中,try塊中尚未執(zhí)行的語句和其他的catch塊將被忽略。若try塊產(chǎn)生的異常對象與第一個catch塊不匹配,系統(tǒng)將自動轉(zhuǎn)到第二個catch塊進(jìn)行匹配,依次類推,直到找到一個可以接收該異常對象的catch塊,即完成流程的跳轉(zhuǎn)。2526異??偸怯删嚯x產(chǎn)生異常最近的匹配catch代碼段處理如果沒有相應(yīng)的異常處理,則異常被交給上一層try代碼段進(jìn)行處理異常處理的查找依據(jù)類型匹配原則順序進(jìn)行第一個匹配的異常處理被執(zhí)行,當(dāng)異常處理執(zhí)行完畢,程序接著最后一個catch代碼段后的語句執(zhí)行異常處理的順序影響到異常的處理子類異??杀桓割惍惓L幚聿东@不要先捕獲父類異常,再捕獲子類異常如果找不到相應(yīng)的異常處理非GUI程序?qū)⒔Y(jié)束程序執(zhí)行;Applet或GUI程序則回復(fù)到事件處理狀態(tài)catch(Exceptione)
捕獲所有Exceptioncatch(Throwablet)
捕獲Exception和Errorcatch語句塊(1)27盡量避免用一般類型作為catch中指定要捕獲的類型。一般應(yīng)該按照try代碼塊中異??赡墚a(chǎn)生的順序及其真正類型進(jìn)行捕獲和處理,在異常處理中無法訪問try代碼段中聲明的變量因為此時try代碼段已經(jīng)退出了,異常處理所需要的任何信息一般都應(yīng)該通過異常對象來傳遞在使用方法時盡量直接處理該方法可能產(chǎn)生的異常這樣你的程序就會更健壯在使用庫方法之前,應(yīng)該先仔細(xì)閱讀說明文檔那里會介紹方法可能產(chǎn)生的異常以及異常產(chǎn)生的條件在使用各種異常類之前也應(yīng)該先仔細(xì)閱讀說明文檔那里會介紹異常的具體含義及異常產(chǎn)生的條件catch語句塊(2)28在catch代碼段中產(chǎn)生的異常不是由相同try的后續(xù)catch代碼段處理,而是由包含整個try-catch結(jié)構(gòu)的上層try代碼段檢測并處理可以把catch到的異常對象再次拋出,使上層try-catch結(jié)構(gòu)繼續(xù)處理該異常事件;也可以把異常對象轉(zhuǎn)換為其它異常對象…catch(Exceptione){
throwe;
}try-catch機制不該被用于流程控制,異常情形應(yīng)該是很稀少的,而不是經(jīng)常性的在catch代碼段中的return語句用于退出方法,而不是返回到異常拋出點(throwpoint)catch語句塊(3)29publicclassExceptionDemo{publicstaticvoidmain(Stringargs[]){try{FileInputStreamfis=newFileInputStream("test1.txt");intb;while((b=fis.read())!=-1){ System.out.print(b);}fis.close();
}catch(FileNotFoundExceptione){
…
}catch(IOExceptione){
…
}}}}catch(IOExceptione){
…}catch(FileNotFoundExceptione){
…//永遠(yuǎn)不會被執(zhí)行}9.4.1
拋出異常(throw語句)30
聲明異常首先必須生成異常。前面所提到的異?;蛘呤怯蒍ava虛擬機生成,或者是由Java類庫中的某些類生成。事實上,我們在程序中也可以生成自己的異常對象,也即是異??梢圆皇浅鲥e產(chǎn)生,而是人為地拋出。不論那種方式,生成異常對象都是通過throw語句實現(xiàn):
throw
newThrowableObject();
ArithmeticExceptione=newArithmeticException();
throwe;
注意:拋出的異常必須是Throwable或其子類的實例。31拋出異常使用throw語句拋出的異常對象的語法格式為:在一個方法內(nèi)使用throw拋出異常對象,若該方法內(nèi)部沒有用try-catch對這個拋出的異常進(jìn)行處理,則此方法應(yīng)聲明拋出異常,由其調(diào)用著處理。異常拋出點后的代碼在拋出異常后不再執(zhí)行,也可以說異常的拋出終止了代碼段的執(zhí)行。任何從Throwable派生的類都可以用throw語句拋出,拋出異常用來表明程序遇到的錯誤無法正常執(zhí)行而需要異常處理throw由異常類所產(chǎn)生的對象;32classJavaThrow{ publicstaticvoidmain(Stringargs[]) {}}try{thrownewArithmeticException();}catch(ArithmeticExceptionae){System.out.println(ae);}try{thrownewArrayIndexOutOfBoundsException();}catch(ArrayIndexOutOfBoundsExceptionai){System.out.println(ai);}try{thrownewStringIndexOutOfBoundsException();}catch(StringIndexOutOfBoundsExceptionsi){System.out.println(si);}33importjava.util.Scanner;publicclassDance1{publicstaticvoidmain(String[]args){Scannerkeyboard=newScanner(System.in);System.out.println("Enternumberofmaledancers:");intmen=keyboard.nextInt();System.out.println("Enternumberoffemaledancers:");intwomen=keyboard.nextInt();if(men==0&&women==0){System.out.println("沒有一個學(xué)員.");System.exit(0);}elseif(men==0){System.out.println("沒有男學(xué)員.");System.exit(0);}elseif(women==0){System.out.println("沒有女學(xué)員.");System.exit(0);}
System.out.println("有學(xué)員,可以開課.");}}沒有使用異常的例子34importjava.util.Scanner;publicclassDance2{publicstaticvoidmain(String[]args){Scannerkeyboard=newScanner(System.in);System.out.println("Enternumberofmaledancers:");intmen=keyboard.nextInt();System.out.println("Enternumberoffemaledancers:");intwomen=keyboard.nextInt();try{if(men==0&&women==0)thrownewException("沒有一個學(xué)員.");elseif(men==0)thrownewException("沒有男學(xué)員.");elseif(women==0)thrownewException("沒有女學(xué)員.");}catch(Exceptione){System.out.println(e.getMessage());System.exit(0);}System.out.println("有學(xué)員,可以開課.");}}改造成使用異常的例子359.4.2聲明異常(throws語句)
如果在一個方法中生成了異常,但是該方法并不處理它產(chǎn)生的異常,而是沿著調(diào)用層次向上傳遞,交由調(diào)用它的方法來處理這些異常,這就是聲明異常。通常的情況是在該方法中并不確切知道改如何對這些異常進(jìn)行處理,比如FileNotFoundException類異常,它由FileInputStream的構(gòu)造方法產(chǎn)生,但在其構(gòu)造方法中并不清楚如何處理它,是終止程序的執(zhí)行還是新生成一個文件,這需要由調(diào)用它的方法來處理。36
聲明異常的方法
聲明異常的方法是在產(chǎn)生異常的方法名后面加上要拋出(throws)的異常的列表:retTypemethodName([paramlist])throwsexceptionList例如類FileInputStream中的read()方法是這樣定義的:publicintread()throwsIOException{…}throws子句中可以同時指明多個異常,說明該方法將不對這些異常進(jìn)行處理,而是聲明拋棄它們。需要強調(diào)的是:對于非運行時異常,程序中必須要作處理,或者捕獲,或者聲明拋棄;而對于運行時異常,程序中則可不處理。[修飾符]返回值類型
方法名([參數(shù)列表])
throws
異常類列表沒有處理異常時,throws語句可以保證編譯通過如果在一個程序中的異常沒有用try-catch語句捕獲異常和處理異常的代碼,則可以在程序代碼所在的方法聲明的后面用throws關(guān)鍵字聲明該方法要拋出異常,將該異常拋出到該方法的調(diào)用方法中,一直可追溯到main()方法,JVM肯定要處理的,這樣編譯就可以通過了。在方法聲明中添加throws子句表示方法將拋出異常。教材
例9.537由方法拋出異常交系統(tǒng)處理由一對于程序需要處理的異常,一般編寫try-catch-finally語句捕獲并處理,而對于程序中無法處理必須交由系統(tǒng)處理的異常,由于系統(tǒng)直接調(diào)用的是主方法main(),所以可以在主方法中使用throws子句聲明拋出異常交由系統(tǒng)處理,編譯能通過,運行也沒問題。教材
例9.63839publicmethod1(){intx;try{x=System.in.read();compute(x);}catch(IOExceptionioe){System.out.println(“readerror”);}catch(ArithmeticExceptione){System.out.println(“devidedby0”);}}publicintcompute(intx)throwsArithmeticException{intz=100/x;returnz;}method1compute異常異常拋出處理調(diào)用40捕獲異常-finally語句finally語句捕獲異常的最后一步是通過finally語句為異常處理提供一個統(tǒng)一的出口,使得在控制流程轉(zhuǎn)到程序的其他部分以前,能夠?qū)Τ绦虻臓顟B(tài)作統(tǒng)一的管理。
無論try所指定的程序塊中是否拋出異常,也無論catch語句的異常類型是否與所拋棄的異常的類型一致,finally所指定的代碼都要被執(zhí)行,它提供了統(tǒng)一的出口。(finally語句與switch中的default語句是不同的!)通常在finally語句中可以進(jìn)行資源的清除工作,如關(guān)閉打開的文件、刪除臨時文件等。41try{
in=newFileInputStream(“file1.txt”);
對文件進(jìn)行處理的程序;}catch(IOExceptione){//對文件異常進(jìn)行處理;}finally{//不論是否發(fā)生異常,都關(guān)閉文件;}finally在文件處理時非常有用
異常的覆蓋
finally代碼段中應(yīng)該把可能產(chǎn)生異常的語句用try-catch保護起來if(in!=null){try{in.close();}catch(IOExceptione){…}}//使用try-catch結(jié)構(gòu),防止finally代碼段拋出異常9.5自定義異常類系統(tǒng)定義的異常類主要用來處理系統(tǒng)可以預(yù)見且較常見的運行錯誤。創(chuàng)建用戶自定義異常時,一般需完成如下工作:用戶自定義的
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞務(wù)生產(chǎn)合同范本
- 保安帶電 自營合同范本
- 企業(yè)形象合同范本
- 公證送達(dá)合同范本
- 上船押金合同范本
- 共同領(lǐng)養(yǎng)寵物合同范本
- 勾調(diào)顧問合作協(xié)議合同范本
- 公司租賃民房合同范本
- 勞保中標(biāo)合同范本
- 農(nóng)田包地合同范本
- 《中國人口老齡化》課件
- 靜脈采血最佳護理實踐相關(guān)知識考核試題
- 檢驗檢測中心檢驗員聘用合同
- 腰椎后路減壓手術(shù)
- 商場扶梯安全培訓(xùn)
- 《全科醫(yī)學(xué)概論》課件-以家庭為單位的健康照顧
- 自來水廠安全施工組織設(shè)計
- 《跟單信用證統(tǒng)一慣例》UCP600中英文對照版
- 《醫(yī)院應(yīng)急培訓(xùn)》課件
- 提高教育教學(xué)質(zhì)量深化教學(xué)改革措施
- 招標(biāo)代理機構(gòu)遴選投標(biāo)方案(技術(shù)標(biāo))
評論
0/150
提交評論