第7章 JAVA異常處理_第1頁(yè)
第7章 JAVA異常處理_第2頁(yè)
第7章 JAVA異常處理_第3頁(yè)
第7章 JAVA異常處理_第4頁(yè)
第7章 JAVA異常處理_第5頁(yè)
已閱讀5頁(yè),還剩33頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第7章異常處理7.1異常的基本概念

7.2異常類(lèi)的繼承架構(gòu)

7.3拋出異常

7.4編寫(xiě)自己的異常類(lèi)

7.1異常的基本概念

異常也稱(chēng)為例外,是在程序運(yùn)行過(guò)程中發(fā)生的、會(huì)打斷程序正常執(zhí)行的事件。下面是幾種常見(jiàn)的異常:

(1)算術(shù)異常(ArithmeticException)。

(2)沒(méi)有給對(duì)象開(kāi)辟內(nèi)存空間時(shí)會(huì)出現(xiàn)空指針異常(NullPointerException)。

(3)找不到文件異常(FileNotFoundException)。

所以在程序設(shè)計(jì)時(shí),必須考慮到可能發(fā)生的異常事件,并做出相應(yīng)的處理,這樣才能保證程序的正常運(yùn)行。

7.1.1異常處理的目的

在沒(méi)有異常處理的語(yǔ)言中,必須使用if或switch等語(yǔ)句,配合所設(shè)想得到的錯(cuò)誤狀況來(lái)捕捉程序中所有可能發(fā)生的錯(cuò)誤。但為了捕捉這些錯(cuò)誤,編寫(xiě)出來(lái)的程序代碼中經(jīng)常有很多if語(yǔ)句,有時(shí)即使這樣也未必能捕捉到所有的錯(cuò)誤,而且這樣做勢(shì)必導(dǎo)致程序運(yùn)行效率的降低。

Java的異常處理機(jī)制恰好改進(jìn)了這一點(diǎn),它具有易于使用,可自行定義異常類(lèi),處理拋出異常的同時(shí)不會(huì)降低程序的運(yùn)行速度等優(yōu)點(diǎn)。因而在Java程序設(shè)計(jì)時(shí),應(yīng)充分地利用Java的異常處理機(jī)制,以增進(jìn)程序的穩(wěn)定性,提高效率。7.1.2簡(jiǎn)單的異常范例

Java本身已有相當(dāng)好的機(jī)制來(lái)處理異常的發(fā)生。本節(jié)主要介紹Java是如何處理異常的。下例TestException7_1是一個(gè)錯(cuò)誤的程序,它在訪問(wèn)數(shù)組時(shí),下標(biāo)值已超過(guò)了數(shù)組下標(biāo)所容許的最大值,因此會(huì)有異常發(fā)生。

【例7-1】TestException7_1.java。在編譯時(shí)程序不會(huì)發(fā)生任何錯(cuò)誤,但是在執(zhí)行到第6行時(shí)會(huì)產(chǎn)生下列錯(cuò)誤信息:

Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException:10

atTestException7_1.main(TestException7_1.java:6)

錯(cuò)誤的原因在于數(shù)組的下標(biāo)值超出了最大允許的范圍。Java發(fā)現(xiàn)這個(gè)錯(cuò)誤之后,便由系統(tǒng)拋出“ArrayIndexOutOf

BoundsException”這個(gè)種類(lèi)的異常,用來(lái)表示錯(cuò)誤的原因,并停止運(yùn)行程序。如果沒(méi)有編寫(xiě)相應(yīng)的處理異常的程序代碼,則Java的默認(rèn)異常處理機(jī)制會(huì)先拋出異常,然后停止程序運(yùn)行。7.1.3發(fā)生異常時(shí)的處理

TestException7_1的異常發(fā)生后,Java便把這個(gè)異常拋了出來(lái),可是拋出來(lái)之后沒(méi)有程序代碼去捕捉它,所以程序到第6行便結(jié)束,程序根本不會(huì)執(zhí)行到第7行。如果加上捕捉異常的程序代碼,則可針對(duì)不同的異常做妥善的處理。這種處理的方式稱(chēng)為異常處理。

異常處理是由try、catch與finally三個(gè)關(guān)鍵字所組成的程序塊,其語(yǔ)法如下:上述語(yǔ)法是依據(jù)下列的順序來(lái)處理異常的:

(1)?try程序塊若有異常發(fā)生,則程序的運(yùn)行便中斷,并拋出“異常類(lèi)所產(chǎn)生的對(duì)象”。

(2)拋出的對(duì)象如果屬于catch括號(hào)內(nèi)欲捕捉的異常類(lèi),則catch會(huì)捕捉此異常,然后進(jìn)到catch的塊中繼續(xù)運(yùn)行。

(3)無(wú)論try程序塊是否捕捉到異常,或者捕捉到的異常是否與catch括號(hào)中的異常相同,最后一定都會(huì)運(yùn)行finally塊中的程序代碼。

(4)?finally的程序代碼塊運(yùn)行結(jié)束后,程序再回到try-catch-finally塊之后繼續(xù)執(zhí)行。由上述過(guò)程可知,異常捕捉過(guò)程中做了兩個(gè)判斷:第一個(gè)是try程序塊是否有異常產(chǎn)生,第二個(gè)是產(chǎn)生的異常是否和catch括號(hào)內(nèi)欲捕捉的異常相同。值得一提的是,finally塊是可以省略的。如果省略了finally塊不寫(xiě),則在catch塊運(yùn)行結(jié)束后,程序跳到try-catch塊之后繼續(xù)執(zhí)行。根據(jù)這些基本概念與運(yùn)行的步驟,可以繪制出如圖7-1所示的流程圖。

異常處理的語(yǔ)法格式中,“異常類(lèi)”指由程序拋出的對(duì)象所屬的類(lèi),例如例7-1中出現(xiàn)的“ArrayIndexOutOfBoundsException”就屬于異常類(lèi)的一種。至于有哪些異常類(lèi)以及它們之間的繼承關(guān)系,本書(shū)后面小節(jié)將做更進(jìn)一步的探討。下面的程序代碼加入了try與catch,使得程序本身具有捕捉異常與處理異常的能力。圖7-1異常處理的流程圖輸出結(jié)果:

數(shù)組超出綁定范圍!

這里一定會(huì)被執(zhí)行!

main()方法結(jié)束!

程序說(shuō)明:

(1)第7行聲明一個(gè)名為arr的整型數(shù)組,并開(kāi)辟了5個(gè)數(shù)據(jù)空間。

(2)第8行為數(shù)組中的第10個(gè)元素賦值,此時(shí)已經(jīng)超出了該數(shù)組本身的范圍,所以會(huì)出現(xiàn)異常。發(fā)生異常之后,程序語(yǔ)句轉(zhuǎn)到catch語(yǔ)句中去處理,程序通過(guò)finally代碼塊統(tǒng)一結(jié)束。

(3)第5~9行的try塊用來(lái)檢查是否有異常發(fā)生。若有異常發(fā)生,且拋出的異常屬于ArrayIndexOutOfBoundsException類(lèi),則運(yùn)行第10~13行的代碼塊。因?yàn)榈?行所拋出的異常正是ArrayIndexOutOfBoundsException類(lèi),所以第12行會(huì)輸出“數(shù)組超出綁定范圍!”字符串。由本例可看出,通過(guò)異常機(jī)制,即使程序運(yùn)行時(shí)發(fā)生問(wèn)題,只要能捕捉到異常,程序便能順利地運(yùn)行到最后,且還能適時(shí)地加入對(duì)錯(cuò)誤信息的提示。

(4)第10行如果捕捉到了異常,則在catch括號(hào)內(nèi)的異常類(lèi)ArrayIndexOutOfBoundsException之后生成一個(gè)對(duì)象e,利用此對(duì)象可以得到異常的相關(guān)信息。下例說(shuō)明了類(lèi)對(duì)象e的應(yīng)用。例7-3省略了finally塊,但程序依然可以運(yùn)行。在第10行中,把catch后括號(hào)內(nèi)的內(nèi)容想象成方法的參數(shù),而e就是ArrayIndexOutOfBoundsException類(lèi)的對(duì)象。對(duì)象e接收到由異常類(lèi)所產(chǎn)生的對(duì)象之后,就進(jìn)到第11行,輸出“數(shù)組超出綁定范圍!”這一字符串,而第12行則輸出異常所屬的種類(lèi),也就是java.lang.ArrayIndexOutOfBoundsException。java.lang正是ArrayIndexOutOfBoundsException類(lèi)所屬的包。

7.1.4異常處理的方法

當(dāng)異常發(fā)生時(shí),通??梢杂脙煞N方法來(lái)處理:一種是交由Java默認(rèn)的異常處理機(jī)制進(jìn)行處理。采用這種處理方式時(shí),Java通常只能輸出異常信息,接著便終止程序的運(yùn)行。例如,TestException7_1的異常發(fā)生后,Java默認(rèn)的異常處理機(jī)制會(huì)顯示:

Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException:10

atTestException7_1.main(TestException7_1.java:6)

接著結(jié)束TestException7_1的運(yùn)行。

另一種處理方式是自行編寫(xiě)try-catch-finally塊來(lái)捕捉異常,如TestException7_2與TestException7_3。自行編寫(xiě)程序代碼來(lái)捕捉異常最大的好處是:可以靈活操控程序的流程,且可做出最適當(dāng)?shù)奶幚?。圖7-2繪出了異常處理機(jī)制的選擇流程。圖7-2異常處理的方法

7.2異常類(lèi)的繼承架構(gòu)

異常可分為兩大類(lèi):java.lang.Exception類(lèi)與java.lang.Error類(lèi)。這兩個(gè)類(lèi)均繼承自java.lang.Throwable類(lèi)。圖7-3為T(mén)hrowable類(lèi)的繼承關(guān)系圖。從圖中可以看出,Java異常事件分為兩大類(lèi):一大類(lèi)繼承Error類(lèi),另一大類(lèi)繼承Exception類(lèi)。圖7-3Throwable

類(lèi)的繼承關(guān)系圖習(xí)慣上將Error與Exception類(lèi)統(tǒng)稱(chēng)為異常類(lèi),但這兩者本質(zhì)上還是有所不同的。Error類(lèi)專(zhuān)門(mén)用來(lái)處理嚴(yán)重影響程序運(yùn)行的錯(cuò)誤,可是通常程序設(shè)計(jì)者不會(huì)設(shè)計(jì)程序代碼去捕捉這種錯(cuò)誤,其原因在于即使捕捉到它,也無(wú)法給予適當(dāng)?shù)奶幚恚鏙ava虛擬機(jī)出錯(cuò)就屬于一種Error。不同于Error類(lèi),Exception類(lèi)包含了一般性異常,這些異常通常在捕捉到之后便可做妥善的處理,以確保程序繼續(xù)運(yùn)行,如TestException7_2中所捕捉到的ArrayIndexOutOfBoundsException就屬于這種異常。從圖7-3所示的異常類(lèi)的繼承關(guān)系圖中可以看出:Exception類(lèi)擴(kuò)展出數(shù)個(gè)子類(lèi),其中IOException、RuntimeException是較常用的兩種。RuntimeException即使不編寫(xiě)異常處理的程序代碼,依然可以編譯成功,而這種異常必須在程序運(yùn)行時(shí)才有可能發(fā)生。與RuntimeException不同的是,IOException一定要編寫(xiě)異常處理的程序代碼才行,它通常用來(lái)處理與輸入/輸出相關(guān)的操作,如文件的訪問(wèn)、網(wǎng)絡(luò)的連接等。當(dāng)異常發(fā)生時(shí),發(fā)生異常的語(yǔ)句代碼會(huì)拋出一個(gè)異常類(lèi)的實(shí)例化對(duì)象,之后此對(duì)象與catch語(yǔ)句中類(lèi)的類(lèi)型進(jìn)行匹配,然后在相應(yīng)的catch中進(jìn)行處理。

7.3拋出異常

前兩節(jié)介紹了try-catch-finally程序塊的編寫(xiě)方法,本節(jié)將介紹如何拋出(throw)異常,以及如何由try-catch來(lái)接收所拋出的異常。拋出異常有下列兩種方式:

(1)在程序中拋出異常。

(2)指定方法拋出異常。

7.3.1在程序中拋出異常

在程序中拋出異常時(shí),一定要用到throw這個(gè)關(guān)鍵字,其語(yǔ)法如下:

throw異常類(lèi)實(shí)例對(duì)象;

從上述格式中可以看出,在throw后面拋出的是一個(gè)異常類(lèi)的實(shí)例對(duì)象。

【例7-4】TestException7_4.java。程序說(shuō)明:

(1)該程序是要計(jì)算a/b的值。因b是除數(shù),故不能為0。若b為0,則系統(tǒng)會(huì)拋出ArithmeticException異常,代表除到0這個(gè)數(shù)。

(2)在try塊中,利用第8行來(lái)判斷除數(shù)b是否為0。如果b=0,則運(yùn)行第9行的throw語(yǔ)句,拋出ArithmeticException異常;如果b不為0,則輸出a/b的值。在此例中強(qiáng)制把b設(shè)為0,因此try塊的第9行會(huì)拋出異常,并由第13行的catch捕捉到異常。

(3)拋出異常時(shí),throw關(guān)鍵字所拋出的是異常類(lèi)的實(shí)例對(duì)象,因此第9行的throw語(yǔ)句必須使用new關(guān)鍵字來(lái)產(chǎn)生對(duì)象。7.3.2指定方法拋出異常

如果方法內(nèi)的程序代碼可能會(huì)發(fā)生異常,且方法內(nèi)又沒(méi)有使用任何代碼塊來(lái)捕捉這些異常,則必須在聲明方法時(shí)一并指明所有可能發(fā)生的異常,以便讓調(diào)用此方法的程序得以做好準(zhǔn)備來(lái)捕捉異常。也就是說(shuō),如果方法會(huì)拋出異常,則可將處理此異常的try-catch-finally塊寫(xiě)在調(diào)用此方法的程序代碼內(nèi)。如果要由方法拋出異常,則方法必須采用下面的語(yǔ)法來(lái)聲明:

方法名稱(chēng)(參數(shù)…)throws異常類(lèi)1,異常類(lèi)2,…

下例指定由方法來(lái)拋出異常,注意此處把main()方法與add()方法編寫(xiě)在同一個(gè)類(lèi)內(nèi)。程序說(shuō)明:

(1)第1~10行聲明一個(gè)Test類(lèi),此類(lèi)中有一個(gè)add(inta,intb)方法,但在此方法后用throws關(guān)鍵字拋出一個(gè)Exception異常。

(2)第15行實(shí)例化一個(gè)Test對(duì)象t。

(3)在第16行調(diào)用Test類(lèi)中的add()方法。

從上面的編譯結(jié)果可以看出,如果在類(lèi)的方法中用throws拋出一個(gè)異常,則在調(diào)用它的地方就必須明確地用try-catch來(lái)捕捉。 7.4編寫(xiě)自己的異常類(lèi)

Java可通過(guò)繼承的方式編寫(xiě)自己的異常類(lèi)。因?yàn)樗锌商幚淼漠惓n?lèi)均繼承自Exception類(lèi),所以自定義異常類(lèi)也必須繼承這個(gè)類(lèi)。自己編寫(xiě)異常類(lèi)的語(yǔ)法格式如下:

可以在自定義異常類(lèi)中編寫(xiě)方法來(lái)處理相關(guān)的事件,甚至不編寫(xiě)任何語(yǔ)句也可正常地工作,這是因?yàn)楦割?lèi)Exception已提供了相當(dāng)豐富的方法,通過(guò)繼承,子類(lèi)均可使用它們。程序說(shuō)明:

(1)第1~8行聲明一個(gè)DefaultException

類(lèi),此類(lèi)繼承自Exception類(lèi),所以此類(lèi)

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論