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

下載本文檔

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

文檔簡(jiǎn)介

第7章Java異常處理7.1異常處理概述7.2異常處理機(jī)制7.3finally子句7.4自定義異常

7.1異常處理概述

編寫一個(gè)Java程序,打開本地磁盤下的D:\test.txt文件。編譯代碼時(shí)的顯示結(jié)果如圖7.1所示。

由編譯信息可知,以上程序?qū)a(chǎn)生FileNotFoundException異常。因此,若希望程序正確運(yùn)行,編譯器需能夠處理FileNotFoundException異常。圖7.1例7-1的運(yùn)行結(jié)果7.1.1異常處理基礎(chǔ)

異常即程序運(yùn)行過程中發(fā)生的異常事件,如例7-1所描述。程序運(yùn)行時(shí)出現(xiàn)異常則生成異常對(duì)象,生成的異常對(duì)象被交給Java虛擬機(jī),Java虛擬機(jī)尋找相應(yīng)的代碼來處理這一異常。生成異常對(duì)象并把它交給Java虛擬機(jī)的過程稱為拋出(throw)異常。在Java虛擬機(jī)得到一個(gè)異常對(duì)象后,它將會(huì)尋找處理這一異常的代碼。尋找異常處理方法的過程從生成異常的方法開始,沿著方法的調(diào)用棧逐層回朔,直到找到包含相應(yīng)異常處理的方法為止。然后,Java虛擬機(jī)把當(dāng)前異常對(duì)象交給這個(gè)方法進(jìn)行處理。這一過程稱為捕獲(catch)異常。如果查遍整個(gè)調(diào)用棧仍然沒有找到合適的異常處理方法,Java虛擬機(jī)將終止Java程序的執(zhí)行。

Java異常處理過程通過5個(gè)關(guān)鍵字控制:try、catch、finally、throw和throws。其中,try、catch和finally構(gòu)成異常處理的完整語法。

try{

//異常監(jiān)控區(qū)域代碼塊

}

catch(ExceptionTypee){

//ExceptionType類型異常處理

}

finally{

//方法返回前需執(zhí)行的代碼塊

}

try語句塊表示要嘗試運(yùn)行的代碼塊,try語句塊中代碼受異常監(jiān)控,其中代碼發(fā)生異常時(shí),會(huì)拋出異常對(duì)象。

catch語句塊會(huì)捕獲try代碼塊中發(fā)生的異常,并在其代碼塊中做異常處理。catch語句帶一個(gè)Throwable類型的參數(shù),表示可捕獲的異常類型。當(dāng)try中出現(xiàn)異常時(shí),catch會(huì)捕獲到發(fā)生的異常,并和自己的異常類型匹配,若匹配,則執(zhí)行catch塊中代碼,并將catch塊參數(shù)指向所拋的異常對(duì)象。catch語句可以有多個(gè),用來匹配多個(gè)異常。某個(gè)異常與catch塊一旦匹配成功,就不再嘗試匹配別的catch塊了。通過異常對(duì)象可以獲取異常發(fā)生時(shí)完整的Java虛擬機(jī)堆棧信息,以及異常信息和異常發(fā)生的原因等。

finally語句塊是緊跟在catch語句后的語句塊,不管try語句塊是否發(fā)生異常該語句塊總會(huì)被執(zhí)行。finally語句塊總是在方法返回前執(zhí)行,目的是給程序一個(gè)補(bǔ)救的機(jī)會(huì)。這也體現(xiàn)了Java語言的健壯性。

throw和throws的用法描述如下。

publicstaticvoidtest()throwsException{

//拋出一個(gè)檢查異常

thrownewException(“方法test中的Exception”);

}

throw關(guān)鍵字用于方法體內(nèi)部,用來拋出一個(gè)Throwable類型的異常。如果拋出了檢查異常,則還應(yīng)該在方法頭部聲明,方法可能拋出的異常類型。該方法的調(diào)用者也必須檢查和處理拋出的異常。如果所有方法都層層上拋獲取的異常,最終Java虛擬機(jī)會(huì)進(jìn)行處理,處理也很簡(jiǎn)單,就是打印異常消息和堆棧信息。如果拋出的是Error或RuntimeException,則該方法的調(diào)用者可選擇處理該異常。7.1.2異常的分類

Java把異常當(dāng)作對(duì)象來處理,并定義一個(gè)基類java.lang.Throwable作為所有異常的超類。在JavaAPI中已經(jīng)定義了許多異常類,這些異常類分為兩大類:錯(cuò)誤(Error)和異常(Exception)。Java異常體系結(jié)構(gòu)呈樹狀,其層次結(jié)構(gòu)如圖7.2所示。圖7.2Java異常體系結(jié)構(gòu)所有異常類型都是內(nèi)置類Throwable的子類,因此,Throwable在異常類層次結(jié)構(gòu)的頂層。Thorwable類有兩個(gè)子類Error和Exception,分別表示錯(cuò)誤和異常。其中異常類Exception又分為運(yùn)行時(shí)異常(RuntimeException)和非運(yùn)行時(shí)異常,這兩種異常有很大的區(qū)別,也稱之為不檢查異常(UncheckedException)和檢查異常(CheckedException)。下面將詳細(xì)講述這些異常之間的區(qū)別與聯(lián)系。

1.Error與Exception類

Error類是錯(cuò)誤類,表示僅靠程序本身無法修復(fù)的嚴(yán)重錯(cuò)誤,如內(nèi)存溢出錯(cuò)誤(OutOfMemoryError)、線程死亡錯(cuò)誤(ThreadDeath)等。這類異常發(fā)生時(shí),Error類對(duì)象由Java虛擬機(jī)生成并拋出給系統(tǒng)。本章不再討論關(guān)于Error類型的異常處理,因?yàn)樗鼈兺ǔJ菫?zāi)難性的致命錯(cuò)誤,不是程序可以控制的。

Exception類是異常類,表示程序本身可以處理的異常。它從父類Throwable中繼承了成員變量和成員方法,只在自身類中聲明了一些構(gòu)造方法。程序中的每一個(gè)異常對(duì)應(yīng)于Exception類的一個(gè)子類實(shí)例,異常對(duì)象中包含異常的位置和特征信息。這種異常分兩大類:運(yùn)行時(shí)異常和非運(yùn)行時(shí)異常。程序應(yīng)當(dāng)盡可能去處理這些異常。

2.運(yùn)行時(shí)異常和非運(yùn)行時(shí)異常

運(yùn)行時(shí)異常都是RuntimeException類及其子類異常,如空對(duì)象異常(NullPointerException)、算術(shù)異常(ArithmeticException)、類型強(qiáng)制轉(zhuǎn)換異常(ClassCastException)、數(shù)組下標(biāo)越界異常(ArrayIndexOutOfBoundsException)、數(shù)值格式異常(NumberFormatException)等。這些異常是不檢查異常,程序可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯(cuò)誤引起的,程序應(yīng)該從邏輯角度盡可能避免這類異常的發(fā)生。非運(yùn)行時(shí)異常是RuntimeException以外的異常,類型上都屬于Exception類及其子類,如IOException、SQLException等。這些異常是檢查異常,從程序語法角度講是必須進(jìn)行處理的異常,如果不處理,程序就不能通過編譯。一般情況下不自定義檢查異常。7.1.3異常的描述

異常類Exception的超類為Throwable類。Throwable類中定義了方法來檢索與異常相關(guān)的信息,并打印顯示異常發(fā)生的棧跟蹤信息。這些方法的描述見表7.1。程序運(yùn)行結(jié)果如圖7.3所示。圖7.3例7-2的運(yùn)行結(jié)果顯然,printStackTrace()方法可獲得比getMessage()方法更多的信息。

7.2異常處理機(jī)制

7.2.1捕獲和處理異常

盡管Java運(yùn)行時(shí)由系統(tǒng)提供的默認(rèn)異常處理程序?qū)τ谡{(diào)試很有用,但程序員通常都希望能手動(dòng)處理異常。這樣做有兩個(gè)好處。第一,允許修正錯(cuò)誤。第二,防止程序自動(dòng)終止。但Java異常的捕獲和處理是一件不容易把握的事情,如果處理不當(dāng),不但會(huì)讓程序的可讀性大大降低,而且導(dǎo)致系統(tǒng)性能低下,甚至引發(fā)一些難以發(fā)現(xiàn)的錯(cuò)誤。為防止和處理一個(gè)運(yùn)行時(shí)錯(cuò)誤,只需要把所要監(jiān)控的代碼放進(jìn)一個(gè)try語句塊。緊跟try語句塊的是一個(gè)能夠捕獲程序員所希望的錯(cuò)誤類型的catch語句塊。下面的程序包含一個(gè)處理例7-1中FileNotFoundException異常的try語句塊和catch語句塊。圖7.4例7-3的運(yùn)行結(jié)果注意在異常發(fā)生時(shí),try語句塊中的“System.out.println("Afteropening");”語句是不會(huì)被執(zhí)行的。一旦異常被引發(fā),程序控制由try語句塊轉(zhuǎn)到catch語句塊,而不會(huì)從catch語句塊返回到try語句塊。一旦執(zhí)行了catch語句,程序控制從整個(gè)try/catch塊的下面一行繼續(xù)。一個(gè)try語句塊和它的catch語句塊形成了一個(gè)單元,try語句塊不能單獨(dú)使用。一個(gè)catch語句塊的范圍受限于前面所定義的try語句塊,它不能捕獲另一個(gè)try語句塊聲明所引發(fā)的異常。catch語句的參數(shù)類似于方法的聲明,包括一個(gè)異常類型和一個(gè)異常對(duì)象。異常類型必須為Throwable類的子類,它指明了catch語句所處理的異常類型。異常對(duì)象在try語句塊中生成并被捕獲,異常對(duì)象名可以是任意標(biāo)識(shí)符,但通常用小寫字母e作為異常對(duì)象名,表示異常對(duì)象。某些情況下,單個(gè)代碼段可能引發(fā)多個(gè)異常。處理這種情況,需要定義兩個(gè)或更多的catch語句塊,每個(gè)語句塊捕獲一種類型的異常。當(dāng)異常被引發(fā)時(shí),Java虛擬機(jī)從上到下將當(dāng)前異常對(duì)象的類型和每個(gè)catch語句處理的異常類型進(jìn)行比較,直到找到最匹配的catch語句為止。當(dāng)一個(gè)catch語句執(zhí)行以后,其他的catch語句被忽略,執(zhí)行從try/catch塊以后的第一行代碼繼續(xù)。這里,類型匹配是指catch所處理的異常類型與生成的異常對(duì)象的類型或者是它的父類完全一致。當(dāng)D:\test.txt文件不存在時(shí),程序發(fā)生FileNotFoundException異常,運(yùn)行結(jié)果如圖7.5所示。圖7.5例7-4的運(yùn)行結(jié)果當(dāng)D:\test.txt文件存在時(shí),程序不會(huì)發(fā)生FileNotFoundException異常。程序向下執(zhí)行并發(fā)生ArrayIndexOutOfBoundsException異常,運(yùn)行結(jié)果如圖7.6所示。圖7.6例7-4的另一個(gè)運(yùn)行結(jié)果當(dāng)有多個(gè)catch語句時(shí),catch語句的排列順序應(yīng)該是從特殊異常到一般異常,即異常子類必須排在它們?nèi)魏胃割愔?。比如有兩個(gè)catch語句分別處理ArithmeticException和Exception兩類異常對(duì)象,則ArithmeticException類的catch語句要寫在Exception類的catch語句之前。通常最后一個(gè)catch語句的異常類參數(shù)都聲明為Exception,這樣能夠保證捕獲和處理所有的異常對(duì)象。7.2.2聲明拋出異常

在有些情況下,一個(gè)方法并不需要處理它所生成的異常,或者不知道該如何處理這一異常,這時(shí)它就向上傳遞,由調(diào)用它的方法來處理這些異常。throws語句就用來處理這種情況。throws語句用于方法的聲明中,用來聲明該方法可能要拋出的異常類型。該方法的調(diào)用者必須捕獲并處理該類型的異常,這樣就實(shí)現(xiàn)了異常對(duì)象在方法之間的傳遞。包含一個(gè)throws語句的方法聲明的通用形式如下:

typemethod-name(exception-list)throwsexception-list

{

//bodyofmethod

}

這里,exception-list是該方法可以引發(fā)的以逗號(hào)分割的異常列表。

【例7-5】錯(cuò)誤的示例。該例試圖引發(fā)一個(gè)它不能捕獲的異常。因?yàn)槌绦驔]有指定一個(gè)throws子句來聲明這一事實(shí),程序?qū)o法編譯。

publicclassExample7_5{

staticvoidthrowOne(){

System.out.println(“InsidethrowOne.”);

thrownewIllegalAccessException(“demo”);

}

publicstaticvoidmain(Stringargs[]){

throwOne();

}

}

【例7-6】正確的示例。為編譯例7.5的程序,需對(duì)其進(jìn)行以下修改:①聲明throwOne()方法引發(fā)IllegalAccessException異常;②main()方法必須定義一個(gè)try/catch語句來捕獲該異常。

publicclassExample7_6{

staticvoidthrowOne()throwsIllegalAccessException{

System.out.println(“InsidethrowOne.”);

thrownewIllegalAccessException(“demo”);

}

publicstaticvoidmain(Stringargs[]){

try{

throwOne();

}

catch(IllegalAccessExceptione){

System.out.println(“Caught”+e);

}

}

}圖7.7例7-6的運(yùn)行結(jié)果7.3finally子句

異常改變了程序正常的執(zhí)行流程。如例7-4所示,程序打開了文件D:\test.txt后發(fā)生異常,此時(shí)文件尚未關(guān)閉,將導(dǎo)致文件寫入失敗。如果程序使用了文件、Socket、JDBC連接之類的資源,即使遇到了異常,也要正確釋放占用的資源。為此,Java提供了一個(gè)簡(jiǎn)化這類操作的關(guān)鍵詞finally。finally創(chuàng)建一個(gè)代碼塊,該代碼塊在一個(gè)try/catch塊完成之后另一個(gè)try/catch塊出現(xiàn)之前執(zhí)行。finally塊無論有沒有異常引發(fā)都會(huì)被執(zhí)行,這在關(guān)閉文件句柄和釋放任何在方法開始時(shí)被分配的其他資源是很有用的。

try、catch、finally三個(gè)語句塊均不能單獨(dú)使用,三者可以組成try...catch...finally、try...catch、try...finally三種結(jié)構(gòu)。catch語句可以有一個(gè)或多個(gè),finally語句最多一個(gè)。try、catch、finally三個(gè)代碼塊中變量的作用域僅限于代碼塊內(nèi)部,分別獨(dú)立且不能相互訪問。如果要在三個(gè)塊中都可以訪問,則需要將變量定義到這些塊的外面。

例7.7顯示

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論