第6章 異常處理_第1頁
第6章 異常處理_第2頁
第6章 異常處理_第3頁
第6章 異常處理_第4頁
第6章 異常處理_第5頁
已閱讀5頁,還剩32頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第六章異常處理1【學習目標】1.了解什么是錯誤和異常。2.熟悉異常對象類型和異常處理機制。3.掌握異常處理的編程技術(shù)。4.能夠建立自己的異常類。2異常是導致程序中斷運行的一種指令流,如果不對異常進行正確的處理,則可能導致程序的中斷執(zhí)行,造成不必要的損失,所以在程序的設(shè)計中必須要考慮各種異常的發(fā)生,并正確地做好相應(yīng)的處理,這樣才能保證程序正常地執(zhí)行。在JAVA中一切的異常都秉著面向?qū)ο蟮脑O(shè)計思想,所有的異常都以類和對象的形式存在,除了JAVA中已經(jīng)提供的各種異常類外,用戶也可以根據(jù)需要定義自己的異常類。任何程序都可能存在問題。在程序?qū)嶋H的應(yīng)用中,可能存在大量的未知問題,所以在程序的開發(fā)中對于錯誤的處理是極其重要的。任何程序都很難做到百分百完美,所以程序開發(fā)中一定要對各種問題進行處理,而JAVA提供的異常處理機制可以幫用戶更好地解決這方面的問題。3在沒有異常處理的語言中如果要回避異常,就必須使用大量的判斷語句,配合所想到的錯誤狀況來捕捉程序中所有可能發(fā)生的錯誤。但為了捕捉這些錯誤,編寫出來的程序代碼經(jīng)常有大量的判斷語句,有時這樣也未必能捕捉到所有的錯誤,而且這樣做勢必導致程序運行效率的降低。JAVA的異常處理機制恰好改進了這一點。它具有易于使用、可自行定義異常類、處理拋出的異常同時又不會降低程序運行的速度等優(yōu)點。因而在JAVA程序設(shè)計時,應(yīng)充分地利用JAVA的異常處理機制,以增進程序的穩(wěn)定性及效率。46.1異常概述一、錯誤與異常根據(jù)錯誤性質(zhì)將運行錯誤分為兩類:錯誤和異常。

1.致命性的錯誤

如程序進入了死循環(huán),或遞歸無法結(jié)束,或內(nèi)存溢出,這類現(xiàn)象稱為錯誤。

2.非致命性的異常

如運算時除數(shù)為0,或操作數(shù)超出數(shù)據(jù)范圍,或打開一個文件時,發(fā)現(xiàn)文件并不存在,或欲裝入的類文件丟失,或網(wǎng)絡(luò)連接中斷等,這類現(xiàn)象稱為異常。51.拋出異常當程序發(fā)生異常時,產(chǎn)生一個異常事件,生成一個異常對象,并把它提交給運行系統(tǒng),再由運行系統(tǒng)尋找相應(yīng)的代碼來處理異常。這個過程稱為拋出(throw)一個異常。一個異常對象可以由Java虛擬機生成,也可以由運行的方法生成。2.捕獲異常異常拋出后,運行時系統(tǒng)從生成對象的代碼開始,沿方法的調(diào)用棧逐層回溯查找,直到包含相應(yīng)處理的方法,并把異常對象交給該方法為止,這個過程稱為捕獲(catch)一個異常。6

3.異常處理的類層次

Java通過錯誤類(Error)和異常類(Exception)來處理錯誤和異常,而它們都是Throwable類的子類,分別用來處理兩組異常。它們的層次結(jié)構(gòu)如圖6-1所示。74.程序?qū)﹀e誤與異常的三種處理方式⑴

程序不能捕獲和處理的錯誤

Error類為錯誤類。⑵

程序應(yīng)避免而不捕獲的異常

對于運行時異常類(RuntimeException),如數(shù)組越界等,無須使用try-catch-finally語句,這類異常應(yīng)通過程序調(diào)試盡量避免而不是去捕獲它。⑶

必須捕獲的異常

有些異常在編寫程序時是無法預料了,如文件沒找到異常、網(wǎng)絡(luò)通信失敗異常等。因此,為了保證程序的健壯性,Java要求必須對可能出現(xiàn)這些異常的代碼使用try-catch-finally語句,否則編譯無法通過。8常見的非運行時異常非運行時異常異常描述CloneNotsupportedException當試圖克隆一個沒有實現(xiàn)Cloneable接口的對象時拋出此異常InterruptedException當線程在很長一段時間內(nèi)一直處于正在等待、休眠或暫停狀態(tài),而另一個線程用Thread類中的interrupt方法中斷它時拋出該異常ClassNotFoundException當程序使用Class類中的forName方法,或者ClassLoader類中的findSystemClass方法和loadClass方法試圖載入某個類而沒有找到時拋出此異常InstantiationException當要被實例化的類是抽象類或接口時拋出此異常IllegalAccessException當某個方法試圖載入其沒有權(quán)限訪問的類時拋出此異常NoSuchMethodException當某個特定的方法無法找到時拋出此異常IOException表示I/0操作時可能產(chǎn)生的各種異常9例6.1文件沒有找到異常類importjava.io.*;publicclassTry3{publicstaticvoidmain(Stringargs[])

{

FileInputStreamfis=newFileInputStream("auto.bat");

System.out.println("Icannotfoundthisfile!");

}}

105.常見的運行時異常類

下面介紹常見的異常類,它們都是RuntimeException的子類。

⑴算術(shù)異常ArithmeticException

⑵空指針異常NullPointerException

⑶類型強制轉(zhuǎn)換異常ClassCastException

⑷數(shù)組負下標異常NegativeArraySizeException

⑸數(shù)組下標越界異常ArrayIndexOutOfBoundsException11運行時異常異常描述ArrayStoreException試圖將錯誤類型的對象存儲到一個對象數(shù)組時拋出此異常ArithmeticException當出現(xiàn)異常的運算條件時拋出此異常,如整數(shù)除以零ClassCastException當兩個沒有所屬關(guān)系的類的實例進行類型轉(zhuǎn)換時拋出此異常IllegalArgumentException當不合法的變量或不適當?shù)膮?shù)被傳遞給方法時拋出此異常IndexOutOfBoundsException索引越界ArrayIndexOutOfBoundsException數(shù)組索引小于0或者超過數(shù)組的最大長度時拋出此異常StringIndexOutOfBoundsException字符串索引小于0或者超過數(shù)組的最大長度時拋出此異常NegativeArraySizeException如果試圖創(chuàng)建一個長度為負數(shù)的數(shù)組時拋出此異常NullPointerException當對象沒有實例化就試圖通過該對象的變量訪問它時拋出此異常SecurityException由安全管理器拋出的異常,指示存在安全侵犯UnsupportedOperationException當不支持請求的操作時,拋出該異常常見的運行時異常(這些異常,大家在編譯運行程序時,會經(jīng)常遇到,需要修改程序)126.2異常處理一、異常的產(chǎn)生以【例6.2】產(chǎn)生數(shù)組下標越界異常和除數(shù)為0異常為例引出異常的產(chǎn)生。例6.2產(chǎn)生數(shù)組下標越界異常和除數(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的異常處理機制中,提供了try-catch-finally語句來捕獲和處理一個或多個異常,語法格式如下:

try

{

<語句1>

}

catch(ExceptionType1e)

{

<語句2>

}…

finally

{

<語句3>

}14

其中,<語句1>是可能產(chǎn)生異常的代碼;<語句2>是捕獲某種異常對象時進行處理的代碼,ExceptionType1代表某種異常類,e為相應(yīng)的對象;<語句3>是其后必須執(zhí)行的代碼,無論是否捕獲到異常。catch語句可以有一個或多個,但至少要有一個catch語句,finally語句可以省略。try-catch-finally語句的作用是,當try語句中的代碼產(chǎn)生異常時,根據(jù)異常的不同,由不同catch語句中的代碼對異常進行捕獲并處理;如果沒有異常,則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ù)組下標越界異常!");

}

finally{

System.out.println("fianllyi="+i);

}

}

}}16⑴try語句try語句大括號{}中的這段代碼可能會拋出一個或多個異常。也就是說,當某段代碼在運行時可能產(chǎn)生異常的話,需要使用try語句來試圖捕獲這些異常。通過這個例子我們再來深入討論try-catch-finally語句,以及使用時要注意的問題。17⑵catch語句 ExceptionDemo6.javacatch語句的參數(shù)類似于方法的聲明,包括一個異常類型和一個異常對象。

catch語句可以有多個,分別處理不同類型的異常。Java運行時系統(tǒng)從上向下分別對每個catch語句處理的異常類型進行檢測,直到找到與類型相匹配的catch語句為止。

如果程序產(chǎn)生的異常和所有catch的處理的異常都不匹配,則這個異常將由Java虛擬機捕獲并處理,此時與不使用try-catch-finally語句是一樣的,這顯然也不是我們所期望的結(jié)果。因此一般在使用catch語句時,最后一個將捕獲Exception這個所有異常的超類,從而保證異常由對象自身來捕獲和處理。也就是,一般先安排子類,再安排父類,否則編譯時編譯器會提示錯誤。18⑶finally語句try所限定的代碼中,當拋出一個異常時,其后的代碼不會被執(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");//溢出時拋出異常

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)鍵字,<異常類>是方法要拋出的異常類,可以聲明多個異常類,用逗號隔開。

注意:將throws子句與throws在語法和使用上要加以區(qū)別。⑵由調(diào)用方法處理異常

由一個方法拋棄異常后,系統(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");

//溢出時拋出異常

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("沒有命令行第一個參數(shù)");}

catch(ArithmeticExceptione){

System.out.println("算數(shù)運算錯誤");}

}}276.4自定義異常類

雖然Java已經(jīng)預定義了很多異常類,但有的情況下,程序員不僅需要自己拋出異常,還要創(chuàng)建自己的異常類。這時可以通過創(chuàng)建Exception的子類來定義自己的異常類。28Java異常類體系中不包含所需要的異常類型。用戶需要將自己所提供類的異常與其他人提供的異常進行區(qū)分。類中將多次拋出這種類型的異常。如果使用其它程序包中定義的異常類,將影響程序包的獨立性與自包含性。下面給出一些原則,提示讀者何時需要自己定義異常類。滿足下列任何一種或多種情況就應(yīng)該考慮自己定義異常類。29Throwable定義的幾個常用方法方法描述ThrowablefillStackTrace()返回一個包含完整堆棧軌跡的Throwable對象,該對象可能被再次引發(fā)StringgetLocalizedMessage()返回一個異常的局部描述StringgetMessage()返回一個異常的描述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項目拓展編寫一個程序,對數(shù)組下標越界的異常進行捕捉和處理,操作方法如下。(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ù)組下標越界,產(chǎn)生異常:"+e);

}

finally{

if(i<10)

System.out.println("i="+i+","+"nums[i]="+nums[i]);

}

}

}}34(2)在上面的程序中,定義的數(shù)組范圍是number[0]~number[9],當i循環(huán)到10的時候,數(shù)組越界,產(chǎn)生異常。在Exception類的所有子類中都

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論