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

下載本文檔

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

文檔簡介

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

6.1異?常?的?概?念

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

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

}

}

}

程序運行結(jié)果為

Thereisanerror!

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

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

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

調(diào)用IntArrayAdd方法

if(發(fā)生錯誤)

輸出錯誤信息

else

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

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

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

6.2Java語言異常的處理

6.2.1try-catch塊

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

try{

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

}

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

//錯誤的處理

}

finally{

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

}

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

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

由于可以將一個派生類對象看成是一個超類的對象,因此,如果多個catch塊后的異常類有繼承關系,則應將派生類放在前面。例如,當程序中數(shù)組下標超界時,Java拋擲出ArrayIndexOutOfBoundsExeption類的異常對象,該異常類是Exception的派生類,因此應將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而如果將兩個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í)行第一個catch塊,輸出:

Thereisanexception

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

finally塊對于try-catch塊是可選的,當try部分的代碼正常執(zhí)行完或發(fā)生異常由某個catch塊捕獲進行處理后執(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++;

}

}

}

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

Helloworld!

Thisisalwaysprinted

No,Imeanit!

Thisisalwaysprinted

HELLOWORLD!!

Thisisalwaysprinted

Re-settingIndexValue

Thisisalwaysprinted6.2.2異常的拋擲

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

thrownewException();

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

●?publicException();

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

如果一個方法成員有可能拋擲異常,應在定義該方法成員時使用throws關鍵字聲明其可能拋擲的異常種類,在方法定義的頭部加上:

throws異常類名列表

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

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

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

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

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

importjava.io.IOException;

classKeyboardInput{

staticintReadInt()throwsException

{

Stringstr=ReadLine();

try{

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

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

}

}

staticdoubleReadDouble()throwsException{

Stringstr=ReadLine();

try{

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

}catch(NumberFormatExceptione){

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

} }

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類有兩個直接子類:Error和Exception。

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

另一個異常類的分支是Exception類和它的子類。在編程中,對錯誤的處理主要是對這類錯誤的處理。類Exception是普通程序可以從中恢復的所有標準異常的超類。

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

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

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

classMyExceptionextendsException{

privateintErrorCode;

MyException(intecode){

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

ErrorCode=ecode;

}

publicintgetErrorCode(){

returnErrorCode;

}

}

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

thrownewMyException(1);

程序6.4演示了異常類的定義、異常拋擲和捕捉。程序運行后從鍵盤輸入10個英文字母,如果輸入非英文字母的字符,則拋擲自定義的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)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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

提交評論