




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第六章異常處理1【學(xué)習(xí)目標(biāo)】1.了解什么是錯(cuò)誤和異常。2.熟悉異常對象類型和異常處理機(jī)制。3.掌握異常處理的編程技術(shù)。4.能夠建立自己的異常類。2異常是導(dǎo)致程序中斷運(yùn)行的一種指令流,如果不對異常進(jìn)行正確的處理,則可能導(dǎo)致程序的中斷執(zhí)行,造成不必要的損失,所以在程序的設(shè)計(jì)中必須要考慮各種異常的發(fā)生,并正確地做好相應(yīng)的處理,這樣才能保證程序正常地執(zhí)行。在JAVA中一切的異常都秉著面向?qū)ο蟮脑O(shè)計(jì)思想,所有的異常都以類和對象的形式存在,除了JAVA中已經(jīng)提供的各種異常類外,用戶也可以根據(jù)需要定義自己的異常類。任何程序都可能存在問題。在程序?qū)嶋H的應(yīng)用中,可能存在大量的未知問題,所以在程序的開發(fā)中對于錯(cuò)誤的處理是極其重要的。任何程序都很難做到百分百完美,所以程序開發(fā)中一定要對各種問題進(jìn)行處理,而JAVA提供的異常處理機(jī)制可以幫用戶更好地解決這方面的問題。3在沒有異常處理的語言中如果要回避異常,就必須使用大量的判斷語句,配合所想到的錯(cuò)誤狀況來捕捉程序中所有可能發(fā)生的錯(cuò)誤。但為了捕捉這些錯(cuò)誤,編寫出來的程序代碼經(jīng)常有大量的判斷語句,有時(shí)這樣也未必能捕捉到所有的錯(cuò)誤,而且這樣做勢必導(dǎo)致程序運(yùn)行效率的降低。JAVA的異常處理機(jī)制恰好改進(jìn)了這一點(diǎn)。它具有易于使用、可自行定義異常類、處理拋出的異常同時(shí)又不會(huì)降低程序運(yùn)行的速度等優(yōu)點(diǎn)。因而在JAVA程序設(shè)計(jì)時(shí),應(yīng)充分地利用JAVA的異常處理機(jī)制,以增進(jìn)程序的穩(wěn)定性及效率。46.1異常概述一、錯(cuò)誤與異常根據(jù)錯(cuò)誤性質(zhì)將運(yùn)行錯(cuò)誤分為兩類:錯(cuò)誤和異常。
1.致命性的錯(cuò)誤
如程序進(jìn)入了死循環(huán),或遞歸無法結(jié)束,或內(nèi)存溢出,這類現(xiàn)象稱為錯(cuò)誤。
2.非致命性的異常
如運(yùn)算時(shí)除數(shù)為0,或操作數(shù)超出數(shù)據(jù)范圍,或打開一個(gè)文件時(shí),發(fā)現(xiàn)文件并不存在,或欲裝入的類文件丟失,或網(wǎng)絡(luò)連接中斷等,這類現(xiàn)象稱為異常。51.拋出異常當(dāng)程序發(fā)生異常時(shí),產(chǎn)生一個(gè)異常事件,生成一個(gè)異常對象,并把它提交給運(yùn)行系統(tǒng),再由運(yùn)行系統(tǒng)尋找相應(yīng)的代碼來處理異常。這個(gè)過程稱為拋出(throw)一個(gè)異常。一個(gè)異常對象可以由Java虛擬機(jī)生成,也可以由運(yùn)行的方法生成。2.捕獲異常異常拋出后,運(yùn)行時(shí)系統(tǒng)從生成對象的代碼開始,沿方法的調(diào)用棧逐層回溯查找,直到包含相應(yīng)處理的方法,并把異常對象交給該方法為止,這個(gè)過程稱為捕獲(catch)一個(gè)異常。6
3.異常處理的類層次
Java通過錯(cuò)誤類(Error)和異常類(Exception)來處理錯(cuò)誤和異常,而它們都是Throwable類的子類,分別用來處理兩組異常。它們的層次結(jié)構(gòu)如圖6-1所示。74.程序?qū)﹀e(cuò)誤與異常的三種處理方式⑴
程序不能捕獲和處理的錯(cuò)誤
Error類為錯(cuò)誤類。⑵
程序應(yīng)避免而不捕獲的異常
對于運(yùn)行時(shí)異常類(RuntimeException),如數(shù)組越界等,無須使用try-catch-finally語句,這類異常應(yīng)通過程序調(diào)試盡量避免而不是去捕獲它。⑶
必須捕獲的異常
有些異常在編寫程序時(shí)是無法預(yù)料了,如文件沒找到異常、網(wǎng)絡(luò)通信失敗異常等。因此,為了保證程序的健壯性,Java要求必須對可能出現(xiàn)這些異常的代碼使用try-catch-finally語句,否則編譯無法通過。8常見的非運(yùn)行時(shí)異常非運(yùn)行時(shí)異常異常描述CloneNotsupportedException當(dāng)試圖克隆一個(gè)沒有實(shí)現(xiàn)Cloneable接口的對象時(shí)拋出此異常InterruptedException當(dāng)線程在很長一段時(shí)間內(nèi)一直處于正在等待、休眠或暫停狀態(tài),而另一個(gè)線程用Thread類中的interrupt方法中斷它時(shí)拋出該異常ClassNotFoundException當(dāng)程序使用Class類中的forName方法,或者ClassLoader類中的findSystemClass方法和loadClass方法試圖載入某個(gè)類而沒有找到時(shí)拋出此異常InstantiationException當(dāng)要被實(shí)例化的類是抽象類或接口時(shí)拋出此異常IllegalAccessException當(dāng)某個(gè)方法試圖載入其沒有權(quán)限訪問的類時(shí)拋出此異常NoSuchMethodException當(dāng)某個(gè)特定的方法無法找到時(shí)拋出此異常IOException表示I/0操作時(shí)可能產(chǎn)生的各種異常9例6.1文件沒有找到異常類importjava.io.*;publicclassTry3{publicstaticvoidmain(Stringargs[])
{
FileInputStreamfis=newFileInputStream("auto.bat");
System.out.println("Icannotfoundthisfile!");
}}
105.常見的運(yùn)行時(shí)異常類
下面介紹常見的異常類,它們都是RuntimeException的子類。
⑴算術(shù)異常ArithmeticException
⑵空指針異常NullPointerException
⑶類型強(qiáng)制轉(zhuǎn)換異常ClassCastException
⑷數(shù)組負(fù)下標(biāo)異常NegativeArraySizeException
⑸數(shù)組下標(biāo)越界異常ArrayIndexOutOfBoundsException11運(yùn)行時(shí)異常異常描述ArrayStoreException試圖將錯(cuò)誤類型的對象存儲(chǔ)到一個(gè)對象數(shù)組時(shí)拋出此異常ArithmeticException當(dāng)出現(xiàn)異常的運(yùn)算條件時(shí)拋出此異常,如整數(shù)除以零ClassCastException當(dāng)兩個(gè)沒有所屬關(guān)系的類的實(shí)例進(jìn)行類型轉(zhuǎn)換時(shí)拋出此異常IllegalArgumentException當(dāng)不合法的變量或不適當(dāng)?shù)膮?shù)被傳遞給方法時(shí)拋出此異常IndexOutOfBoundsException索引越界ArrayIndexOutOfBoundsException數(shù)組索引小于0或者超過數(shù)組的最大長度時(shí)拋出此異常StringIndexOutOfBoundsException字符串索引小于0或者超過數(shù)組的最大長度時(shí)拋出此異常NegativeArraySizeException如果試圖創(chuàng)建一個(gè)長度為負(fù)數(shù)的數(shù)組時(shí)拋出此異常NullPointerException當(dāng)對象沒有實(shí)例化就試圖通過該對象的變量訪問它時(shí)拋出此異常SecurityException由安全管理器拋出的異常,指示存在安全侵犯UnsupportedOperationException當(dāng)不支持請求的操作時(shí),拋出該異常常見的運(yùn)行時(shí)異常(這些異常,大家在編譯運(yùn)行程序時(shí),會(huì)經(jīng)常遇到,需要修改程序)126.2異常處理一、異常的產(chǎn)生以【例6.2】產(chǎn)生數(shù)組下標(biāo)越界異常和除數(shù)為0異常為例引出異常的產(chǎn)生。例6.2產(chǎn)生數(shù)組下標(biāo)越界異常和除數(shù)為0異常publicclassTry1{
publicstaticvoidmain(Stringargs[])
{
inti=0,j=0;
inta[]={5,6,7,8};
for(i=0;i<5;i++)
System.out.println("a["+i+"]="+a[i]); System.out.println(3/j);
}}13二、使用try-
catch-finally語句捕獲和處理異常
在Java的異常處理機(jī)制中,提供了try-catch-finally語句來捕獲和處理一個(gè)或多個(gè)異常,語法格式如下:
try
{
<語句1>
}
catch(ExceptionType1e)
{
<語句2>
}…
finally
{
<語句3>
}14
其中,<語句1>是可能產(chǎn)生異常的代碼;<語句2>是捕獲某種異常對象時(shí)進(jìn)行處理的代碼,ExceptionType1代表某種異常類,e為相應(yīng)的對象;<語句3>是其后必須執(zhí)行的代碼,無論是否捕獲到異常。catch語句可以有一個(gè)或多個(gè),但至少要有一個(gè)catch語句,finally語句可以省略。try-catch-finally語句的作用是,當(dāng)try語句中的代碼產(chǎn)生異常時(shí),根據(jù)異常的不同,由不同catch語句中的代碼對異常進(jìn)行捕獲并處理;如果沒有異常,則catch語句不執(zhí)行;而無論是否捕獲到異常都必須執(zhí)行finally中的代碼。15例6.3異常捕獲和處理publicclassTry2{
publicstaticvoidmain(Stringargs[]){
inti=0;
inta[]={5,6,7,8};
for(i=0;i<5;i++){
try{
System.out.println("a["+i+"]="+a[i]);
}
catch(ArrayIndexOutOfBoundsExceptione){
System.out.println("數(shù)組下標(biāo)越界異常!");
}
finally{
System.out.println("fianllyi="+i);
}
}
}}16⑴try語句try語句大括號(hào){}中的這段代碼可能會(huì)拋出一個(gè)或多個(gè)異常。也就是說,當(dāng)某段代碼在運(yùn)行時(shí)可能產(chǎn)生異常的話,需要使用try語句來試圖捕獲這些異常。通過這個(gè)例子我們再來深入討論try-catch-finally語句,以及使用時(shí)要注意的問題。17⑵catch語句 ExceptionDemo6.javacatch語句的參數(shù)類似于方法的聲明,包括一個(gè)異常類型和一個(gè)異常對象。
catch語句可以有多個(gè),分別處理不同類型的異常。Java運(yùn)行時(shí)系統(tǒng)從上向下分別對每個(gè)catch語句處理的異常類型進(jìn)行檢測,直到找到與類型相匹配的catch語句為止。
如果程序產(chǎn)生的異常和所有catch的處理的異常都不匹配,則這個(gè)異常將由Java虛擬機(jī)捕獲并處理,此時(shí)與不使用try-catch-finally語句是一樣的,這顯然也不是我們所期望的結(jié)果。因此一般在使用catch語句時(shí),最后一個(gè)將捕獲Exception這個(gè)所有異常的超類,從而保證異常由對象自身來捕獲和處理。也就是,一般先安排子類,再安排父類,否則編譯時(shí)編譯器會(huì)提示錯(cuò)誤。18⑶finally語句try所限定的代碼中,當(dāng)拋出一個(gè)異常時(shí),其后的代碼不會(huì)被執(zhí)行。通過finally語句可以指定一塊代碼,無論try所指定的程序塊中是否拋出異常,也無論catch語句的異常類型是否與所拋出的異常的類型一致,finally所指定的代碼都要被執(zhí)行,它提供了統(tǒng)一的出口。該語句是可以省略的。196.3拋出異常一、使用throw語句拋出異常
使用throw語句拋出異常,格式如下:
throw<異常對象>
其中,throw是關(guān)鍵字,<異常對象>是創(chuàng)建的異常類對象。20例6.4拋出異常publicclassTry5{
publicvoidrun(bytek){
bytey=1,i=1;
System.out.print(k+"!=");//不換行輸出
for(i=1;i<=k;i++){
try{
if(y>Byte.MAX_VALUE/i)//Integer類的常量,表示最大值
thrownewException("overflow");//溢出時(shí)拋出異常
else
y=(byte)(y*i);
}
catch(Exceptione)
{21
System.out.println("exception:"+e.getMessage());
e.printStackTrace();//顯示異常信息
System.exit(0);
}
}
System.out.println(y);
}
publicstaticvoidmain(Stringargs[])
{
Try5a=newTry5();
for(bytei=1;i<10;i++)
a.run(i);
}}22
⑴拋棄異常的方法在方法聲明中,添加throws(拋棄)子句表示該方法將拋出異常。
帶有throws子句的方法的聲明格式如下:[<修飾符>]<返回值類型><方法名>([<參數(shù)列表>])[throws<異常類>]
其中,throws是關(guān)鍵字,<異常類>是方法要拋出的異常類,可以聲明多個(gè)異常類,用逗號(hào)隔開。
注意:將throws子句與throws在語法和使用上要加以區(qū)別。⑵由調(diào)用方法處理異常
由一個(gè)方法拋棄異常后,系統(tǒng)將異常向上傳播,由調(diào)用它的方法來處理這些異常。剛才的例題,我們也可以用拋棄異常的方法來處理,Try6.java二、拋棄異常的方法與調(diào)用方法處理異常23例6.5拋出異常的方法與調(diào)用方法處理異常publicclassTry6{
publicvoidcalc(bytek)throwsException{
//拋出異常
bytey=1,i=1;
System.out.print(k+"!=");
for(i=1;i<=k;i++){
try{
if(y>Byte.MAX_VALUE/i)
//Integer類的常量,表示最大值
thrownewException("overflow");
//溢出時(shí)拋出異常
else
y=(byte)(y*i);
}
catch(Exceptione){
System.out.println("exception:"+e.getMessage());
e.printStackTrace();
System.exit(0);
}
}24
System.out.println(y);
}
publicvoidrun(bytek){//捕獲并處理異常
try{
calc(k);
}
catch(Exceptione){
System.out.println("exception:"+e.getMessage());
e.printStackTrace();
System.exit(0);
}
}
publicstaticvoidmain(Stringargs[]){
Try6a=newTry6();
for(bytei=1;i<10;i++)
a.run(i);
}}25三、由方法拋出異常交系統(tǒng)處理
對于程序中需要處理的異常,一般編寫try-catch-finally語句捕獲并處理;而對于程序中無法處理必須由系統(tǒng)處理的異常,可以使用throw語句在方法中拋出異常交系統(tǒng)處理。26
例如,我們也可以自己根據(jù)編程的需要,拋出異常,并捕獲處理。publicclassDemo1{
//異常用法舉例
staticinta,b,c;
publicstaticvoidmain(Stringargs[]){
try{
a=100;
b=Integer.parseInt(args[0]);
if(b==13)
throw(newArithmeticException());//方法中拋出異常
c=a/b;
System.out.println("a/b="+c);
}
catch(ArrayIndexOutOfBoundsExceptione){
System.out.println("沒有命令行第一個(gè)參數(shù)");}
catch(ArithmeticExceptione){
System.out.println("算數(shù)運(yùn)算錯(cuò)誤");}
}}276.4自定義異常類
雖然Java已經(jīng)預(yù)定義了很多異常類,但有的情況下,程序員不僅需要自己拋出異常,還要?jiǎng)?chuàng)建自己的異常類。這時(shí)可以通過創(chuàng)建Exception的子類來定義自己的異常類。28Java異常類體系中不包含所需要的異常類型。用戶需要將自己所提供類的異常與其他人提供的異常進(jìn)行區(qū)分。類中將多次拋出這種類型的異常。如果使用其它程序包中定義的異常類,將影響程序包的獨(dú)立性與自包含性。下面給出一些原則,提示讀者何時(shí)需要自己定義異常類。滿足下列任何一種或多種情況就應(yīng)該考慮自己定義異常類。29Throwable定義的幾個(gè)常用方法方法描述ThrowablefillStackTrace()返回一個(gè)包含完整堆棧軌跡的Throwable對象,該對象可能被再次引發(fā)StringgetLocalizedMessage()返回一個(gè)異常的局部描述StringgetMessage()返回一個(gè)異常的描述voidprintStackTrace()顯示堆棧軌跡voidprintStackTrace(PrintStreams)把堆棧軌跡輸出到指定的輸出流voidprintStackTrace(PrintWriters)把堆棧軌跡輸出到指定的PrintWriterStringtoString()返回此異常的簡短描述30例6.6自定義異常類 MyException.javaclassMyExceptionextendsException//自定義異常類{
MyException(){}
MyException(Stringmsg)
{
super(msg);}}classUsingMyException//拋出異常類{
Voidf()throwsMyException
{
System.out.println("ThrowsMyExceptionfromf()");
thrownewMyException();
}
Voidg()throwsMyException
{
System.out.println("ThrowsMyExceptionfromg()");
thrownewMyException("originateding()");
}}31publicclassTestMyException//捕獲并處理異常{
publicstaticvoidmain(Stringargs[]){
UsingMyExceptionm=newUsingMyException();//創(chuàng)建自定義異常類對象
try{
m.f();
}
catch(MyExceptione){
e.printStackTrace();
}
try{
m.g();
}
catch(MyExceptione){
e.printStackTrace();
}
}}326.5項(xiàng)目拓展編寫一個(gè)程序,對數(shù)組下標(biāo)越界的異常進(jìn)行捕捉和處理,操作方法如下。(1)打開“記事本”軟件,鍵入如下的程序內(nèi)容:33publicclassShuzuyichang{
publicstaticvoidmain(Stringargs[]){
int[]nums=newint[10];
for(inti=0;i<=10;i++){
try{
nums[i]=i+1;}
catch(ArrayIndexOutOfBoundsExceptione){
System.out.println("數(shù)組下標(biāo)越界,產(chǎn)生異常:"+e);
}
finally{
if(i<10)
System.out.println("i="+i+","+"nums[i]="+nums[i]);
}
}
}}34(2)在上面的程序中,定義的數(shù)組范圍是number[0]~number[9],當(dāng)i循環(huán)到10的時(shí)候,數(shù)組越界,產(chǎn)生異常。在Exception類的所有子類中都
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 法律案例說明課件
- 醫(yī)院醫(yī)療醫(yī)藥報(bào)告模板63
- 2025年商洛b2從業(yè)資格證模擬考試題目
- 小升初-周期問題
- 經(jīng)濟(jì)管理年活動(dòng)
- 幼兒園班主任職責(zé)
- 2025勞動(dòng)合同與服務(wù)協(xié)議的區(qū)別何在
- 二零二五土地租賃終止協(xié)議合同書范例
- 極速小鎮(zhèn)建設(shè)內(nèi)容
- 經(jīng)費(fèi)贊助協(xié)議書二零二五年
- (新版)高級插花花藝師技能認(rèn)證考試復(fù)習(xí)題庫大全-上(單選題)
- 重點(diǎn)工作督查督辦工作制度
- 2024年中國手工空心掛面市場調(diào)查研究報(bào)告
- 勞動(dòng)技能實(shí)操指導(dǎo)(勞動(dòng)教育)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 建筑工地“一懂三會(huì)”消防安全知識(shí)講座
- 中華民族共同體概論課程第十一講 中華一家與中華民族格局底定(清前中期)教案
- 北師大版初中數(shù)學(xué)全部公式
- 2024數(shù)智化綠色低碳評價(jià)管理體系
- 【年產(chǎn)30萬噸尿素生產(chǎn)工藝計(jì)算及流程設(shè)計(jì)9000字(論文)】
- 【基于PLC智能照明控制系統(tǒng)設(shè)計(jì)10000字(論文)】
- 污水處理廠尾水人工濕地及循環(huán)利用項(xiàng)目可行性研究報(bào)告寫作模板-拿地申報(bào)
評論
0/150
提交評論