《Java程序設(shè)計(jì)》課件第6章_第1頁
《Java程序設(shè)計(jì)》課件第6章_第2頁
《Java程序設(shè)計(jì)》課件第6章_第3頁
《Java程序設(shè)計(jì)》課件第6章_第4頁
《Java程序設(shè)計(jì)》課件第6章_第5頁
已閱讀5頁,還剩34頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第6章異常處理6.1異常的概念6.2Java語言異常的處理6.3異常的類型

6.1異?常?的?概?念

6.1.1案例:異常處理方法演示

程序在執(zhí)行過程中可能會發(fā)生多種嚴(yán)重程度不同的錯(cuò)誤,這些錯(cuò)誤與編譯錯(cuò)誤不同,不是程序語法的錯(cuò)誤,而是由運(yùn)行時(shí)遇到的一些特殊情況引起的。例如,由于網(wǎng)絡(luò)的問題不能正常從網(wǎng)絡(luò)服務(wù)器獲取數(shù)據(jù)。程序運(yùn)行時(shí)發(fā)生錯(cuò)誤,Java語言稱之為異常,它會使程序的運(yùn)行流程發(fā)生改變。對于異??梢圆扇《喾N方式進(jìn)行處理,如終止程序運(yùn)行,這是最簡單的方法。當(dāng)然,大多數(shù)情況下用戶不希望采取這種處理方法。當(dāng)發(fā)生錯(cuò)誤時(shí),用戶一般會希望程序能夠給出足夠的錯(cuò)誤信息,繼續(xù)運(yùn)行。因此,一個(gè)好的程序員在編寫程序時(shí),必須預(yù)測程序執(zhí)行過程中可能發(fā)生的各種異常情況。Java語言提供了一種不同于傳統(tǒng)程序設(shè)計(jì)語言的異常處理方法,使程序員可以方便地檢測和處理各種異常情況。下面先看一個(gè)例子?!境绦?.1】異常處理方法演示。

publicclassExceptionDemo

{

staticint[]IntArrayAdd(int[]a,int[]b)

{

int[]c=newint[a.length];

for(inti=0;i<c.length;i++)

c[i]=a[i]+b[i];

returnc;

}

publicstaticvoidmain(String[]args) {

int[]a=newint[20];

int[]b=newint[10];

for(inti=0;i<20;i++)

a[i]=i;

for(inti=0;i<10;i++)

b[i]=i;

try{

int[]c=IntArrayAdd(a,b);

for(inti=0;i<c.length;i++)

System.out.print(""+c[i]);

}catch(Exceptione){

System.out.println(“Thereisanerror!”);

}

}

}

程序運(yùn)行結(jié)果為

Thereisanerror!

從第3章有關(guān)數(shù)組的知識可以知道,程序6.1的main方法在調(diào)用方法IntArrayAdd對數(shù)組b訪問時(shí)下標(biāo)超界,產(chǎn)生一個(gè)異常。由于程序6.1采用了Java語言中的異常處理方法,程序執(zhí)行流程發(fā)生變化,轉(zhuǎn)到語句System.out.println("Thereisanerror!")執(zhí)行。6.1.2異常處理

傳統(tǒng)的程序設(shè)計(jì)語言(例如C)需要程序員檢測錯(cuò)誤發(fā)生的原因并進(jìn)行處理,這樣,就需要在正常執(zhí)行流程中增加一些if-else語句或switch-case語句來檢測函數(shù)的返回值或全局的錯(cuò)誤代碼,判斷發(fā)生了什么類型的錯(cuò)誤。這種處理方法使得程序的流程變得復(fù)雜,難以閱讀理解,而Java語言的異常處理機(jī)制使得錯(cuò)誤信息的處理和流程控制變得很簡單。觀察一下程序6.1可以發(fā)現(xiàn),程序中的錯(cuò)誤在IntArrayAdd方法中發(fā)生,但是該方法中并沒有錯(cuò)誤處理語句,既沒有用返回值標(biāo)志錯(cuò)誤發(fā)生,也沒有設(shè)置一個(gè)main方法和IntArrayAdd方法可以共同訪問的變量用于傳遞錯(cuò)誤信息。那么,錯(cuò)誤信息是怎樣從IntArrayAdd方法傳遞到main方法的呢?

實(shí)際上IntArrayAdd方法在超界訪問數(shù)組元素時(shí)拋擲了一個(gè)異常,創(chuàng)建了一個(gè)異常對象用于存儲錯(cuò)誤信息,由于IntArrayAdd方法沒有處理該異常,Java虛擬機(jī)終止IntArrayAdd方法的執(zhí)行,然后自動返回到main方法,將流程轉(zhuǎn)入異常處理部分。與傳統(tǒng)的錯(cuò)誤處理方法相比,Java語言的異常處理機(jī)制有很多優(yōu)點(diǎn)。它將錯(cuò)誤處理代碼從常規(guī)代碼中分離出來,例如程序6.1的main方法中先調(diào)用IntArrayAdd方法然后輸出結(jié)果,中間并沒有插入錯(cuò)誤處理的代碼,而按照傳統(tǒng)的方法程序的結(jié)構(gòu)應(yīng)該是這樣的:

調(diào)用IntArrayAdd方法

if(發(fā)生錯(cuò)誤)

輸出錯(cuò)誤信息

else

輸出結(jié)果當(dāng)錯(cuò)誤類型較多,需要分別處理時(shí),采用這種方法很顯然會使程序流程變得十分復(fù)雜。

異常處理機(jī)制帶來的另一個(gè)好處是錯(cuò)誤的傳播,Java異常會自動在方法調(diào)用堆棧中傳播,例如程序6.1異常從IntArrayAdd方法自動傳遞到main方法。

另外,Java異常處理機(jī)制克服了傳統(tǒng)方法的錯(cuò)誤信息有限的問題,可以針對不同的錯(cuò)誤類型定義不同的異常類,異常處理機(jī)制會根據(jù)異常對象的類型尋找匹配的錯(cuò)誤處理代碼。

6.2Java語言異常的處理

6.2.1try-catch塊

Java語言中異常的捕捉是通過try-catch塊來實(shí)現(xiàn)的,其語法形式為

try{

//程序正常的流程,有可能拋擲異常

}

catch(異常類名異常對象名){

//錯(cuò)誤的處理

}

finally{

//如果try部分代碼執(zhí)行完或catch部分代碼執(zhí)行完,則執(zhí)行該部分代碼

}

try塊為程序正常的流程,如果發(fā)生異常,則終止try塊的執(zhí)行轉(zhuǎn)入catch塊。對于一個(gè)try塊,可以有多個(gè)catch塊,每個(gè)catch后的異常類名應(yīng)不同,Java語言根據(jù)異常對象的類型從上向下匹配,執(zhí)行第一個(gè)與之匹配的catch塊。

Java語言中所有的異常類都是Throwable類的子類,用戶可以從已有的異常類派生新的類型,用于處理用戶程序中特有的錯(cuò)誤類型。如果找不到匹配的catch塊,則該異常繼續(xù)在調(diào)用堆棧中傳播,傳遞給調(diào)用該方法的方法。

由于可以將一個(gè)派生類對象看成是一個(gè)超類的對象,因此,如果多個(gè)catch塊后的異常類有繼承關(guān)系,則應(yīng)將派生類放在前面。例如,當(dāng)程序中數(shù)組下標(biāo)超界時(shí),Java拋擲出ArrayIndexOutOfBoundsExeption類的異常對象,該異常類是Exception的派生類,因此應(yīng)將ArrayIndexOutOfBounds

Exeption異常類的catch塊放在前面。例如下面的程序段:inta[]=newint[10];

try{

for(inti=0;i<=10;i++)

a[i]=i;

}catch(ArrayIndexOutOfBoundsExeptione){

System.out.println("ArrayIndexoutofBounds");

}catch(Exceptione){

System.out.println("Thereisanexception");

}

該程序段將輸出:

ArrayIndexoutofBounds而如果將兩個(gè)catch塊的順序?qū)φ{(diào),則變成下面的形式:

inta[]=newint[10];

try{

for(inti=0;i<=10;i++)

a[i]=i;

}catch(Exceptione){

System.out.println("Thereisanexception");

}

catch(ArrayIndexOutOfBoundsExeptione){

System.out.println("ArrayIndexoutofBounds");

}將執(zhí)行第一個(gè)catch塊,輸出:

Thereisanexception

catch塊中的異常對象名相當(dāng)于方法中的形式參數(shù),作用范圍為該catch塊,它是對捕捉到的異常對象的引用,可以通過它獲得有關(guān)錯(cuò)誤信息。

finally塊對于try-catch塊是可選的,當(dāng)try部分的代碼正常執(zhí)行完或發(fā)生異常由某個(gè)catch塊捕獲進(jìn)行處理后執(zhí)行其中的代碼。如果沒有匹配的catch,則發(fā)生異常后直接執(zhí)行finally部分的語句。finally語句不被執(zhí)行的唯一情況是在try塊內(nèi)執(zhí)行終止程序的System.exit()方法?!境绦?.2】異常處理的執(zhí)行順序。

publicclassFinallyBlock

{

publicstaticvoidmain(String[]args)

{

inti=0;

Stringgreetings[]={

"Helloworld!",

"No,Imeanit!",

"HELLOWORLD!!"

}; while(i<4){

try{

System.out.println(greetings[i]);

}catch(ArrayIndexOutOfBoundsExceptione){

System.out.println("Re-settingIndexValue");

i=-1;

}finally{

System.out.println("Thisisalwaysprinted");

} i++;

}

}

}

程序運(yùn)行時(shí)重復(fù)輸出下面的內(nèi)容,可按Ctrl+C鍵終止:

Helloworld!

Thisisalwaysprinted

No,Imeanit!

Thisisalwaysprinted

HELLOWORLD!!

Thisisalwaysprinted

Re-settingIndexValue

Thisisalwaysprinted6.2.2異常的拋擲

異常的拋擲是由throw語句來實(shí)現(xiàn)的,如果程序中檢測到一個(gè)錯(cuò)誤,可以創(chuàng)建一個(gè)異常對象,然后使用throw拋擲。例如:

thrownewException();

該語句直接調(diào)用Exception類的構(gòu)造方法創(chuàng)建一個(gè)Exception類的對象并拋擲該對象。Exception類從Throwable類派生而來,含有兩個(gè)構(gòu)造方法:

●?publicException();

●?publicException(Stringmsg)。根據(jù)錯(cuò)誤類型的不同,創(chuàng)建的異常對象的類型也不相同。

如果一個(gè)方法成員有可能拋擲異常,應(yīng)在定義該方法成員時(shí)使用throws關(guān)鍵字聲明其可能拋擲的異常種類,在方法定義的頭部加上:

throws異常類名列表

例如,Thread類的方法sleep的定義為

publicstaticnativevoidsleep(longmills)throwsInterruptedException若采用throws聲明方法拋擲的異常,Java語言編譯器將檢查調(diào)用該方法時(shí)是否進(jìn)行異常捕捉。例如,程序5.3在run方法中調(diào)用線程類Thread類的sleep方法,如果將異常捕捉的語句去掉,編譯時(shí)將提示:

Exception"InterruptedException"notcaughtordeclaredby"voidAd.run()"

該提示信息要求run方法捕捉處理該異常,或在定義run方法時(shí)聲明該方法可能拋擲InterruptedException類型的異常,然后由調(diào)用該方法的代碼捕捉處理該異常。6.2.3實(shí)例

程序6.3演示了try-catch和throw語句的使用,該程序在KeyboardInput類中定義了兩個(gè)靜態(tài)方法ReadInt和ReadDouble,從標(biāo)準(zhǔn)輸入設(shè)備讀取int、double類型數(shù)據(jù)。首先調(diào)用ReadLine方法讀取一行字符串,然后將該字符串轉(zhuǎn)換為int、double類型數(shù)據(jù)。如果在轉(zhuǎn)換的過程中發(fā)生錯(cuò)誤,輸入了錯(cuò)誤的數(shù)據(jù),則拋擲NumberFormatException類的異常,ReadInt和ReadDouble方法捕捉該異常,然后拋擲Exception異常。ExceptionDemo類在main方法中捕捉異常,調(diào)用Exception類的方法getMessage獲取錯(cuò)誤信息?!境绦?.3】異常處理實(shí)例。

importjava.io.IOException;

classKeyboardInput{

staticintReadInt()throwsException

{

Stringstr=ReadLine();

try{

returnnewInteger(str).intValue(); //將讀入的字符串轉(zhuǎn)換為int

}catch(NumberFormatExceptione){ thrownewException("輸入數(shù)據(jù)錯(cuò)誤");

}

}

staticdoubleReadDouble()throwsException{

Stringstr=ReadLine();

try{

returnnewDouble(str).doubleValue(); //將讀入的字符串轉(zhuǎn)換為double

}catch(NumberFormatExceptione){

thrownewException("輸入數(shù)據(jù)錯(cuò)誤");

} }

staticStringReadLine()

{

charin;

Stringinputstr="";

try{

in=(char)System.in.read();

while(in!='\n'){

if(in!='\r')

inputstr=inputstr+in;

in=(char)System.in.read(); }

}

catch(IOExceptione){

inputstr="";

}

returninputstr;

}

}

publicclassExceptionDemo

{ publicstaticvoidmain(String[]args)

{

try{

System.out.println("Theinputdoubleis"+KeyboardInput.ReadDouble());

System.out.println("Theinputintegeris"+KeyboardInput.ReadInt());

}catch(Exceptione){

System.out.println(e.getMessage());

}

}

}

6.3異?常?的?類?型

6.3.1Java異常類層次

Java中的所有的異常類都是從Throwable類派生出來的。Throwable類有兩個(gè)直接子類:Error和Exception。

Error類及其子類主要用來描述一些Java運(yùn)行時(shí)系統(tǒng)內(nèi)部的錯(cuò)誤或資源枯竭導(dǎo)致的錯(cuò)誤,普通的程序不能從這類錯(cuò)誤中恢復(fù)。應(yīng)用程序不能拋擲這種類型的錯(cuò)誤,這類錯(cuò)誤出現(xiàn)的幾率是很小的。

另一個(gè)異常類的分支是Exception類和它的子類。在編程中,對錯(cuò)誤的處理主要是對這類錯(cuò)誤的處理。類Exception是普通程序可以從中恢復(fù)的所有標(biāo)準(zhǔn)異常的超類。

Exception類又有兩個(gè)分支:從RuntimeException中派生出來的類和不是從RuntimeException類中派生的類。這是根據(jù)錯(cuò)誤發(fā)生的原因進(jìn)行分類的。

RuntimeException是程序員編寫程序不正確所導(dǎo)致的異常,RuntimeException類的錯(cuò)誤又包括:錯(cuò)誤的強(qiáng)制類型轉(zhuǎn)換(ClassCastException)、數(shù)組越界訪問(IndexOutOfBoundsException)、空指針操作(NullPointerException)等。這類錯(cuò)誤Java語言不強(qiáng)制要求程序捕獲。而其他的異常則是由于一些異常的情況造成的,不是程序本身的錯(cuò)誤,比如:輸入/輸出錯(cuò)誤(IOException)、試圖為一個(gè)不存在的類找到一個(gè)代表它的class類的對象(ClassNotFoundException)等。這類異常Java語言要求程序必須處理,如果發(fā)生異常的方法本身不處理該異常,則方法頭部必須使用throws。6.3.2創(chuàng)建自己的異常類

用戶定義異常類是通過派生Exception類來創(chuàng)建的,這種異常類可以包含一個(gè)“普通”類所包含的任何東西。下面就是一個(gè)用戶定義異常類的例子,它包含一個(gè)構(gòu)造函數(shù)、幾個(gè)變量以及方法。例如:

classMyExceptionextendsException{

privateintErrorCode;

MyException(intecode){

super(“自定義的異常類型”);

ErrorCode=ecode;

}

publicintgetErrorCode(){

returnErrorCode;

}

}

定義上面的異常類后可以通過下面的語句拋擲MyException類的異常:

thrownewMyException(1);

程序6.4演示了異常類的定義、異常拋擲和捕捉。程序運(yùn)行后從鍵盤輸入10個(gè)英文字母,如果輸入非英文字母的字符,則拋擲自定義的notLetterException類型的異常?!境绦?.4】異常類的定義、異常拋擲和捕捉。

importjava.io.IOException;

classnotLetterExceptionextendsException{ //異常類定義

publicnot

溫馨提示

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

最新文檔

評論

0/150

提交評論