版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第八章異常處理8.1異常處理基礎(chǔ)8.2異常處理語(yǔ)法8.3自定義異常類本章小結(jié)
8.1異常處理基礎(chǔ)
所謂異常,就是程序運(yùn)行時(shí)可能出現(xiàn)的一些不正常、錯(cuò)誤的情況。例如,試圖打開一個(gè)根本不存在的文件、類型轉(zhuǎn)換失敗、數(shù)據(jù)庫(kù)連接異常等,異常處理機(jī)制將會(huì)改變程序的控制流程,讓程序有機(jī)會(huì)對(duì)錯(cuò)誤做出處理。沒(méi)有異常處理機(jī)制的編程語(yǔ)言,對(duì)程序可能出現(xiàn)的異常情況,往往是用很多if-else的分支語(yǔ)句來(lái)盡可能地預(yù)知可能發(fā)生的情況,保證程序的容錯(cuò)性。但是由于我們需要預(yù)測(cè)的可能性太多,代碼將會(huì)劇增,程序?qū)⒆兊脧?fù)雜。
如圖8-1所示是Java異常類的層次結(jié)構(gòu)。
圖8-1Java異常層次圖
在這個(gè)異常類層次最上層的是Throwable,它是java.Lang包中的一個(gè)類,該類的名字類似接口名,但實(shí)際是一個(gè)Java類。Throwable類是Java語(yǔ)言中所有錯(cuò)誤或異常的超類,該類派生了兩個(gè)子類java.lang.Error和java.lang.Exception。圖中最底層的三項(xiàng)分別說(shuō)明如下。
(1)?RuntimeException(運(yùn)行時(shí)異常)。運(yùn)行時(shí)異常是程序運(yùn)行時(shí)自動(dòng)對(duì)某些錯(cuò)誤做出反應(yīng)而產(chǎn)生的,所以對(duì)于運(yùn)行時(shí)異常不需要編寫異常處理的程序代碼,依然可以成功編譯,主要包括算術(shù)異常類、空指針異常類、下標(biāo)越界異常類、數(shù)組元素個(gè)數(shù)為負(fù)異常類、類型強(qiáng)制轉(zhuǎn)換異常類、無(wú)效參數(shù)異常類等等。這類異常應(yīng)通過(guò)檢查程序和程序調(diào)試來(lái)盡量避免,而不是使用try-catch-finally語(yǔ)句捕獲處理,比如a/b,其中的b有可能為0,但是這樣的表達(dá)式是不需要進(jìn)行異常處理的。
(2)其它異常類。其它異常類指的是在Exception類下除了RuntimeException之外的異常類,可以稱之為受檢類異常(CheckedException)。這種異常經(jīng)常是在程序運(yùn)行過(guò)程中由環(huán)境原因造成的,如輸入/輸出I/O異常、網(wǎng)絡(luò)地址不能打開、文件未找到等,對(duì)于受檢類異常必須在程序中使用try-catch-finally語(yǔ)句捕獲并進(jìn)行相應(yīng)的處理,否則不能通過(guò)編譯。這是語(yǔ)法上的強(qiáng)制要求,主要在Java的輸入/輸出程序中比較常見。
(3)各種Error子類。各種Error子類是由系統(tǒng)保留的異常類,該類定義了那些應(yīng)用程序通常無(wú)法捕捉到的錯(cuò)誤,一旦此類錯(cuò)誤發(fā)生,程序就停止運(yùn)行。該類主要包括內(nèi)存溢出錯(cuò)誤類、棧溢出錯(cuò)誤類、類定義未找到錯(cuò)誤類、圖形界面錯(cuò)誤類等。
各種Error子類主要包括OutOfMemoryError、StackOverflowError、NoClassDefFoundError、java.awt.AWTError等。
從上面的描述來(lái)看,Java的異常主要有三類:
(1)程序不能處理的錯(cuò)誤Error;
(2)程序應(yīng)避免而可以不去捕獲的運(yùn)行時(shí)異常RuntimeException;
(3)必須捕獲的非運(yùn)行時(shí)異常CheckedException。
8.2異常處理語(yǔ)法8.2.1try-catch-finally如果程序運(yùn)行過(guò)程中發(fā)生了異常,系統(tǒng)會(huì)捕獲拋出的異常對(duì)象并輸出相應(yīng)的信息,同時(shí)終止程序的運(yùn)行,導(dǎo)致其后的程序無(wú)法運(yùn)行。這可能并不是用戶所期望的,用戶可能更希望由程序來(lái)獲取和處理異常對(duì)象,其它的程序語(yǔ)句則能夠繼續(xù)運(yùn)行,這就是捕獲異常的主要作用,也就是說(shuō),對(duì)可能發(fā)生受檢類異常的語(yǔ)句進(jìn)行監(jiān)控,被監(jiān)控的語(yǔ)句一旦發(fā)生異常,由異常處理機(jī)制來(lái)接管程序,并讓后續(xù)的程序可以繼續(xù)運(yùn)行。
try-catch-finally異常處理語(yǔ)法的格式為
說(shuō)明:
(1)?try塊:監(jiān)控區(qū)主要是對(duì)可能發(fā)生受檢類異常CheckedException的程序語(yǔ)句段使用try進(jìn)行包圍,而對(duì)于可能發(fā)生Error或者RuntimeException的語(yǔ)句一般不進(jìn)行監(jiān)控。
(2)?catch塊:如果程序需要在catch塊中訪問(wèn)異常對(duì)象的相關(guān)信息,可以通過(guò)catch后異常形參來(lái)獲得,然后在后面的語(yǔ)句塊中進(jìn)行處理。在一個(gè)try-catch-finally的結(jié)構(gòu)中,try塊只有一個(gè),而catch塊可以有多個(gè),表示能對(duì)監(jiān)控區(qū)中的語(yǔ)句進(jìn)行監(jiān)控,可以捕捉多個(gè)可能發(fā)生的異常。
(3)?finally塊:不管監(jiān)控區(qū)是否發(fā)生異常,異常被拋出是否被捕捉到,在try-catch-finally結(jié)構(gòu)的運(yùn)行流程中如果有finally塊,就一定要執(zhí)行finally塊中的語(yǔ)句。finally塊是可以被省略的,它常常被用來(lái)回收一些物理資源,如數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)連接、磁盤文件等。
Java異常處理機(jī)制如圖8-2所示。
圖8-2Java異常處理機(jī)制
如果沒(méi)有異常處理機(jī)制,會(huì)如何?
(1)異常一旦發(fā)生,整個(gè)程序就會(huì)在發(fā)生異常的地方終止運(yùn)行。
(2)如果沒(méi)有異常處理機(jī)制,可以使用if-else的結(jié)構(gòu)來(lái)處理可能發(fā)生的異常,從圖8-2也可以看出異常處理機(jī)制類似于分支結(jié)構(gòu)(注:多分支對(duì)應(yīng)了異常處理可以有多個(gè)catch語(yǔ)句)。
多個(gè)分支結(jié)構(gòu),類似于try-catch-finally中的多個(gè)catch結(jié)構(gòu)。如果有多個(gè)catch語(yǔ)句,要注意catch的排列順序,如果父類的異常類放在前面,子類放在后面,按照向上轉(zhuǎn)型的觀點(diǎn),子類catch就不能捕捉到相應(yīng)的異常對(duì)象,因?yàn)楦割愒谇懊鎸?duì)異常對(duì)象的捕獲進(jìn)行了“攔截”(只要有一個(gè)catch捕捉到異常對(duì)象,后面的catch結(jié)構(gòu)就不再執(zhí)行,這個(gè)與多分支結(jié)構(gòu)if-elseif是邏輯一致的)。有不少“偷懶”的程序員,在監(jiān)控區(qū)后面就只寫一個(gè)catch(Exceptionex),表示對(duì)所有的異常類進(jìn)行捕獲,這樣也滿足了異常處理的語(yǔ)法要求。
當(dāng)try塊一旦發(fā)生異常,系統(tǒng)就會(huì)生成對(duì)應(yīng)的異常類對(duì)象然后拋出,而異常處理機(jī)制就會(huì)依次使用后面的catch語(yǔ)句來(lái)進(jìn)行捕捉;一旦捕獲該異常對(duì)象,會(huì)將該異常對(duì)象賦給catch塊后的異常引用變量,程序就可以通過(guò)該引用變量來(lái)獲取該異常的相關(guān)信息,并進(jìn)行相應(yīng)的處理。下面通過(guò)一個(gè)程序示例來(lái)進(jìn)行說(shuō)明。
程序結(jié)果:
程序結(jié)果:
8.2.2throw/throws
當(dāng)異常發(fā)生時(shí),系統(tǒng)會(huì)將相對(duì)應(yīng)的異常類對(duì)象生成并拋出。如果是Java定義好的運(yùn)行時(shí)異?;蛘咤e(cuò)誤,都由系統(tǒng)自動(dòng)拋出;如果想在程序中主動(dòng)拋出異常或者聲明函數(shù)要拋出異常,可以使用throw或者throws。
1.throw
如果在一個(gè)方法內(nèi)部需要主動(dòng)拋出異常對(duì)象,可以使用throw(第一人稱)進(jìn)行異常拋出,其語(yǔ)法為
throw異常類對(duì)象;
程序結(jié)果:
2.throws
如果是在一個(gè)方法的頭部聲明該方法可能要拋出異常,可以使用throws來(lái)完成(第三人稱單數(shù)加s),其語(yǔ)法為
使用throws聲明拋出異常的一般情況是:當(dāng)前方法不知道如何(或者不想)處理方法中可能發(fā)生的異常,于是不使用try-catch監(jiān)控和捕捉異常,而是在方法聲明中說(shuō)明該方法將有可能拋出異常,由方法的上一級(jí)調(diào)用者處理,自己不再處理。
函數(shù)嵌套調(diào)用可能會(huì)使得異常一層層向上拋出,最后會(huì)拋出到main方法。如果main方法也不進(jìn)行處理,繼續(xù)使用throws聲明拋出異常,而該異常就會(huì)拋出到控制臺(tái)上顯示異常的棧軌跡信息,并中止程序運(yùn)行。
當(dāng)一個(gè)方法在頭部聲明拋出異常后,如果為受檢類異常,則該方法被調(diào)用的時(shí)候就必須用try-catch-finally結(jié)構(gòu)對(duì)該方法監(jiān)控并進(jìn)行異常處理或者繼續(xù)聲明向上拋出,如下列程序所示。
8.3自定義異常類
用戶自定義異常都應(yīng)該繼承Exception類,如果希望自定義運(yùn)行時(shí)異常,則應(yīng)該繼承RuntimeException類。定義異常類時(shí)通常需要提供兩種構(gòu)造函數(shù):一是無(wú)參數(shù)的構(gòu)造函數(shù);二是帶一個(gè)字符串的構(gòu)造函數(shù),這個(gè)字符串將作為該異常對(duì)象的詳細(xì)說(shuō)明(也就是異常對(duì)象的getMessage方法的返回值)。
由于Exception類中具有以下方法,所以自定義異常類也繼承了這幾個(gè)方法:
(1)?getMessage():返回該異常的詳細(xì)描述字符串。
(2)?printStackTrace():將該異常的跟蹤棧軌跡輸出到標(biāo)準(zhǔn)錯(cuò)誤輸出流。
(3)?printStackTrace(PrintStreams):將該異常的跟蹤棧信息輸出到指定輸出流。
(4)?getStackTrace():返回該異常的跟蹤棧軌跡信息。
只有在軟件中自定義異常類,系統(tǒng)才能識(shí)別特定的運(yùn)行錯(cuò)誤,才能及時(shí)對(duì)錯(cuò)誤進(jìn)行控制和處理,這是增強(qiáng)軟件穩(wěn)定性和健壯性的手段之一。用戶自定義異常類不能由系統(tǒng)自動(dòng)拋出,需要在程序中使用throw語(yǔ)句來(lái)定義在什么情況下產(chǎn)生異常,并拋出該自定義異常類的對(duì)象。例如,對(duì)前面的動(dòng)物類做一個(gè)自定義異常類,如果動(dòng)物重量為負(fù)數(shù)(在生成動(dòng)物類對(duì)象或者對(duì)動(dòng)物類的weight進(jìn)行設(shè)置時(shí)進(jìn)行判定),則拋出自定義異常對(duì)象。
程序結(jié)果:
本章小結(jié)
1.按照是否必須進(jìn)行異常處理,異常類可分為兩大類:java.lang.Error類+?RuntimeException類和受檢異常類。前面一類是不需要進(jìn)行異常處理的,在Exception下除了RuntimeException之外的所有類稱為受檢異常類,該類是必須進(jìn)行異常處理的。2.如果沒(méi)有異常處理機(jī)制,一旦發(fā)生異常,系統(tǒng)將拋出異常,并終止程序運(yùn)行。
3.Java的異常處理主要有下列兩種方式:
(1)使用try-catch-finally結(jié)構(gòu),即使用try塊來(lái)監(jiān)控可能發(fā)生異常的程序段,使用catch塊來(lái)捕捉拋出的異常并進(jìn)行處理;catch塊可以有多個(gè),無(wú)論有否異常發(fā)生,是否捕捉到,都要執(zhí)行finally塊語(yǔ)句。該結(jié)構(gòu)類似于if-elseif結(jié)構(gòu)。
(2)如果一個(gè)方法對(duì)方法內(nèi)部的語(yǔ)句不想進(jìn)行異常處理,可以使用throws在函數(shù)頭部進(jìn)行異常拋出聲
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024旋挖鉆孔灌注樁基礎(chǔ)工程施工合同
- 城市污水處理化糞池施工方案
- 初中生課外活動(dòng)安排方案
- 技術(shù)研發(fā)部績(jī)效管理方案
- 果樹采摘機(jī)課程設(shè)計(jì)
- 2024房產(chǎn)轉(zhuǎn)讓合同簡(jiǎn)單協(xié)議
- 2024年臨時(shí)勞務(wù)用工合同樣本
- 化學(xué)品運(yùn)輸車輛安全保障方案
- 2024年大型食堂蔬菜供應(yīng)合同
- 門鈴課程設(shè)計(jì)論文
- 湖南省婁底市漣源市2023-2024學(xué)年上學(xué)期期中質(zhì)量檢測(cè)九年級(jí)英語(yǔ)試卷
- 運(yùn)動(dòng)技能學(xué)習(xí)與控制課件第十一章運(yùn)動(dòng)技能的練習(xí)
- 國(guó)家開放大學(xué)《可編程控制器應(yīng)用實(shí)訓(xùn)》形考任務(wù)5(實(shí)訓(xùn)五)參考答案
- 商業(yè)活動(dòng)港風(fēng)復(fù)古摩登年會(huì)主題方案
- 技術(shù)核定單(示范文本)
- 柴油采購(gòu)?fù)稑?biāo)方案(技術(shù)標(biāo))
- 3.8做改革創(chuàng)新生力軍
- 掛籃檢查驗(yàn)收記錄表
- 快遞員國(guó)家職業(yè)技能標(biāo)準(zhǔn)2019年版
- 作業(yè)設(shè)計(jì)-第六單元生物的多樣性及其保護(hù)
- InfoQ:2023中國(guó)企業(yè)數(shù)字化人才發(fā)展白皮書
評(píng)論
0/150
提交評(píng)論