




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、With JavaBlueJObject firstPLP封面封面清華大學(xué)出版社第8章異常與斷言8.1 Throwable家族 2518.1.1 異常的概念8.1.2 Error和Exception8.1.3 拋出異常8.1.4自定義異常類(lèi)8.2 捕獲和處理2598.2.1 try和catch子句8.2.2 finally子句8.3 斷言2648.3.1 斷言的語(yǔ)義和語(yǔ)法8.3.2 斷言的使用指南錯(cuò)誤是真理的鄰居,因此它欺騙了我們。泰戈?duì)柫魑灱?章引言章引言一個(gè)定義良好的API,包含了使用該方法的前置條件和后置條件。然而,程序運(yùn)行的環(huán)境是復(fù)雜的,程序在執(zhí)行過(guò)程中可能遇到各種錯(cuò)誤。為此,源代碼要
2、為可能遇到錯(cuò)誤做一些準(zhǔn)備。Java程序中所拋出的異常,是對(duì)“異常條件”的封裝、或者說(shuō)是對(duì)調(diào)用者“沒(méi)有遵守基本契約”的抗議。異常對(duì)象告知方法的調(diào)用者:你(或許是環(huán)境)沒(méi)有遵守基本契約。本章將介紹方法執(zhí)行中遇到意外情況時(shí)應(yīng)該如何處理,即Java的異常機(jī)制。為了更好地定義方法接口,本章還介紹了Java的斷言機(jī)制。 8.1 Throwable家族 Java通過(guò)面向?qū)ο蟮姆绞教幚懋惓#畲笙薅鹊卣{(diào)解了程序的正確性和清晰性(可讀性和可維護(hù)性)間的矛盾。8.1.1 異常的概念異常的概念 方法在執(zhí)行時(shí)可能會(huì)遇到意外。錯(cuò)誤根源:錯(cuò)誤環(huán)境錯(cuò)誤環(huán)境或非法參數(shù)非法參數(shù)。作為方法的設(shè)計(jì)者,通常希望方法被調(diào)用時(shí)滿足其前置
3、條件,但是,不能夠因?yàn)檎{(diào)用者沒(méi)有遵守契約如在網(wǎng)絡(luò)服務(wù)器未啟動(dòng)時(shí)發(fā)出網(wǎng)絡(luò)連接請(qǐng)求,于是服務(wù)代碼就導(dǎo)致死機(jī)、死循環(huán)或其他后果,而是拋出異常。1. 必須考慮可能發(fā)生的異常事件必須考慮可能發(fā)生的異常事件 服務(wù)的設(shè)計(jì)者,必須考慮到可能發(fā)生的異常事件、必須考慮拋出異常對(duì)象、做好本方法的文檔使方法具有良好的接口。方法的設(shè)計(jì)者有義務(wù)對(duì)方法參數(shù)的有效性進(jìn)行檢查。不管方法的文檔中是否使用前置條件對(duì)參數(shù)加以明確地說(shuō)明,非法參數(shù)的檢查是方法實(shí)現(xiàn)的第一步。2. 拋出異常拋出異常 if(index=s.length() throw new IndexOutOfBoundsException(); else return
4、s.charAt(index); 假設(shè)不采用異常對(duì)象而使用傳統(tǒng)的錯(cuò)誤處理機(jī)制代碼混雜。功能代碼與錯(cuò)誤處理代碼混雜在一起,嚴(yán)重降低了程序的可讀性。將業(yè)務(wù)邏輯與異常處理分離,可以說(shuō)是Java異常機(jī)制最重要的目的。同一個(gè)錯(cuò)誤沒(méi)有加以數(shù)據(jù)抽象。特殊的返回值問(wèn)題。3. 何謂異常何謂異常 異常(事件)是指方法執(zhí)行中遇到意外/例外/異常的情況/條件,或者說(shuō)在方法執(zhí)行時(shí)所發(fā)生的、使正常流程中斷的事件。exception討論源代碼時(shí)所稱(chēng)的“異?!?,通常指Exception(或它的子類(lèi)的)對(duì)象;當(dāng)說(shuō)道“異常處理”時(shí),是指對(duì)方法執(zhí)行中捕獲的Exception進(jìn)行處理。8.1.2 Error和和Exception 當(dāng)
5、程序執(zhí)行遇到exception,程序是就此結(jié)束運(yùn)行還是應(yīng)該從異常事件中恢復(fù)呢?這就得看exception的嚴(yán)重程度。(1)病入膏肓就讓程序安樂(lè)死,Error (2)大病小災(zāi)還得救死扶傷,checked Exceptions (3)程序bug引起的(不應(yīng)該出現(xiàn)的異常事件)則不予理會(huì)(打電話給編寫(xiě)那段導(dǎo)致異常代碼的程序員,讓他修改)。RuntimeException 1. java.lang.Error 出現(xiàn)Error,除了盡力使程序安全退出外,不需要做太多的事情(回頭修改源代碼是另一回事)。Error的典型子類(lèi)有:LinkageError不兼容性問(wèn)題。ThreadDeath 線程終止錯(cuò)誤Virt
6、ualMachineError Java 虛擬機(jī)崩潰InternalError 意外的內(nèi)部錯(cuò)誤OutOfMemoryError 內(nèi)存溢出或沒(méi)有可用的內(nèi)存提供給垃圾回收器StackOverflowError 堆棧溢出UnknownError 未知但嚴(yán)重的異常java.io.IOError 發(fā)生嚴(yán)重的 I/O 錯(cuò)誤2. java.lang.ExceptionException分成兩大陣營(yíng):RuntimeException和非RuntimeException。 檢查型異常(checked Exceptions),口語(yǔ)化為“必須要處理的異?!?。非檢查異常非檢查異常(Unchecked Exceptio
7、ns)由程序bug引起,應(yīng) 該 在 程 序 的 調(diào) 試 中 改 正 。 算 術(shù) 運(yùn) 算 異 常ArithmeticException(由除0錯(cuò)等導(dǎo)致)、數(shù)組越界異常ArrayIndexOutOfBoundsException等Exception的典型子類(lèi)的典型子類(lèi) ClassNotFoundException 未找到欲裝載的類(lèi)CloneNotSupportedException 克隆未實(shí)現(xiàn)Cloneable的對(duì)象InterruptedException 線程錯(cuò)誤中斷 IOException 輸入、輸出異常.RuntimeException 運(yùn)行期間拋出的異常ArithmeticExceptio
8、n 算術(shù)錯(cuò)誤,例如4/0ClassCastException 無(wú)效的類(lèi)型轉(zhuǎn)換IllegalArgumentException 非法參數(shù)IndexOutOfBoundsException 下標(biāo)越界ArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsExceptionNegativeArraySizeException 用負(fù)數(shù)創(chuàng)建數(shù)組NullPointerException空引用錯(cuò)誤3. 小結(jié)小結(jié) Error:程序員不拋出、不捕捉、不處理。RuntimeException:由系統(tǒng)通過(guò)默認(rèn)的異常處理程序自動(dòng)拋出,自行處理。不強(qiáng)制要求程序員捕捉和處理
9、。調(diào)試程序時(shí)改正。檢查型異常:方法頭中用throws子句聲明,方法體中以throw語(yǔ)句拋出;調(diào)用者以throws子句向上推卸處理責(zé)任、或者使用try-catch捕捉和處理。8.1.3 拋出異常拋出異常 Java程序(包括JDK類(lèi)庫(kù)或第三方包中的代碼)和Java虛擬機(jī)都可能拋出異常。JVM自動(dòng)拋出的異常:我們不想拋出的,如Error、RuntimeException。下面介紹如何在方法體中手工拋出異常。1. throw語(yǔ)句語(yǔ)句 手工拋出異常,指方法在執(zhí)行過(guò)程中遭遇某種異常事件,從而創(chuàng)建相應(yīng)的Throwable對(duì)象并拋出。其語(yǔ)法為:throw aThrowableObject;throw new
10、Dog(),程序?qū)o(wú)法通過(guò)編譯。通常程序中拋出的應(yīng)該是檢查型異常。 異常處理流程一旦執(zhí)行了throw語(yǔ)句,JVM新建一個(gè)異常對(duì)象、終止本方法的執(zhí)行流程,返回到方法的調(diào)用者希望得到處理。 如果該異常是檢查型異常,調(diào)用者(1)準(zhǔn)備了catch子句進(jìn)行異常處理;(2)官僚主義地使用throws子句,將異常處理推到調(diào)用者的調(diào)用者。 如果該異常是非檢查異常,調(diào)用者又沒(méi)有附加的異常處理代碼,系統(tǒng)將調(diào)用默認(rèn)的異常處理流程,在標(biāo)準(zhǔn)輸出設(shè)備上打印/輸出該異常對(duì)象的堆棧使用軌跡。 2. throws子句子句 throws子句在方法頭中說(shuō)明本方法將拋出的若干異常。它不能獨(dú)立存在,僅僅是方法頭的一部分。 () thr
11、ows (1)官僚主義官僚主義 本方法作為客戶程序客戶程序,但是不想處理被調(diào)方法拋出的檢查型異常。于是將所有不想處理的異常通過(guò)throws子句拋給本方法的調(diào)用者。各種Java書(shū)籍在講解IO流、網(wǎng)絡(luò)編程時(shí),為了集中精力,書(shū)中的例程常常使用throws以保持代碼的簡(jiǎn)短。在實(shí)際編程中,官僚主義地throws是不好的風(fēng)格不好的風(fēng)格。許多程序員經(jīng)常忘記處理異常,或者將異常處理推遲到遙遠(yuǎn)的未來(lái)。(2)完善接口完善接口本方法作為服務(wù)程序服務(wù)程序,方法體中使用throw語(yǔ)句拋出的所有檢查型異常所有檢查型異常,必須在方法頭中throws該異常(或者其父類(lèi))。換言之,throws子句嚴(yán)格地強(qiáng)制性要求程序員:方法體
12、中只能夠使用throw語(yǔ)句拋出throws子句中聲明的檢查型異常類(lèi)型或子類(lèi)型。 對(duì)于非檢查型異常,盡管可以不throws,但是為了給調(diào)用者一個(gè)明確的接口,建議也列舉出來(lái)。 8.1.4自定義異常類(lèi)自定義異常類(lèi) 優(yōu)先使用標(biāo)準(zhǔn)庫(kù)的異常。package API.exceptions;public class EmptyQueueException extends Exception public EmptyQueueException(String msg) super(msg); Override public String getMessage()/覆蓋父類(lèi)的方法 return 隊(duì)列已空,執(zhí)行出隊(duì)
13、操作引發(fā)異常; 3. Exception類(lèi)簡(jiǎn)介類(lèi)簡(jiǎn)介 Exception類(lèi)的構(gòu)造函數(shù)有2個(gè):vpublic Exception();vpublic Exception(String s); Exception類(lèi)及其子類(lèi)從超類(lèi)Throwable繼承的常用方法有:vpublic String getMessage() /該方法返回一個(gè)詳細(xì)描述異常的字符串。vpublic void printStackTrace( ) /在當(dāng)前的標(biāo)準(zhǔn)輸出(一般就是屏幕)上打印輸出當(dāng)前異常對(duì)象的堆棧使用軌跡,也即程序先后調(diào)用執(zhí)行了哪些對(duì)象或類(lèi)的哪些方法,使得運(yùn)行過(guò)程中產(chǎn)生了這個(gè)異常對(duì)象。vpublic String
14、toString( ) /該方法返回一個(gè)簡(jiǎn)潔描述該異常的字符串。8.2 捕獲和處理捕獲和處理 方法設(shè)計(jì)者使用throws、throw和自定義異常類(lèi)拋出了異常。方法的使用者則需要捕獲和處理異常。本節(jié)假定使用者不通過(guò)throws將異常處理沿調(diào)用鏈向上推卸一般格式一般格式 trym();catch(Exception e)/異常處理語(yǔ)句finally/防止資源泄露說(shuō)明說(shuō)明可能拋出異常的語(yǔ)句封裝在try塊中,用以捕獲可能發(fā)生的異常 catch子句分別處理不同類(lèi)型的異常。Java運(yùn)行時(shí)系統(tǒng)從上到下依次對(duì)每個(gè)catch子句處理的異常類(lèi)型進(jìn)行檢測(cè),直到找到類(lèi)型相匹配的catch子句為止 無(wú)論有無(wú)異常發(fā)生,最
15、后都必須執(zhí)行finally塊中的語(yǔ)句 try catch()catch()catch()finally 1. try子句子句 如果被調(diào)的方法m()將throws某些檢查型異常,必須將方法調(diào)用語(yǔ)句封裝在try子句中,表示嘗試執(zhí)行。try子句之后必須至少有一個(gè)catch 或 finally塊,可以同時(shí)有兩者。try子句可能需要多個(gè)catch 塊。異常發(fā)生時(shí),按照書(shū)寫(xiě)順序找到第一個(gè)匹配異常對(duì)象類(lèi)型的catch塊并執(zhí)行。2. catch子句子句 catch子句/塊不能夠獨(dú)立存在,它附屬對(duì)應(yīng)的try子句(類(lèi)似else與if的關(guān)系 。如果執(zhí)行過(guò)程中try子句拋出了異常對(duì)象x,JVM按照x的類(lèi)型在catch
16、子句中搜尋匹配的處理代碼。搜索從try后面的第一個(gè)catch子句開(kāi)始,按照源程序的書(shū)寫(xiě)順序,將x的類(lèi)型與catch子句的參數(shù)匹配。8.2.2 finally子句 無(wú)論try子句拋出或不拋出異常,無(wú)論catch子句是否捕獲到異常,finally子句都被執(zhí)行。finally子句是防止資源泄露的關(guān)鍵工具。當(dāng)需要關(guān)閉文件、套接字、流、鎖等資源時(shí),通常將關(guān)閉代碼放在finally子句中以確保資源的釋放,而Java7 引入的try-with-resources語(yǔ)句,為需要關(guān)閉的資源,簡(jiǎn)化了代碼。1. finally子句的典型應(yīng)用子句的典型應(yīng)用 (1)多線程程序中 (2)文件處理時(shí) try( Buffere
17、dReader br = new BufferedReader( new FileReader(file) ) 2. finally子句的執(zhí)行流程子句的執(zhí)行流程 如果因?yàn)闄z查型異常退出try,則執(zhí)行相應(yīng)的catch子句,最后執(zhí)行finally子句。如果因?yàn)榉菣z查型異常、或者(官僚主義地)throws的檢查型異常退出try,一般JVM找不到相應(yīng)的catch子句,因而執(zhí)行finally子句然后返回到上級(jí)調(diào)用者,進(jìn)一步尋求catch子句。3. try-catch-finally語(yǔ)句中使用語(yǔ)句中使用return finally子句中使用return會(huì)嚴(yán)重干擾try和catch的邏輯。除了總是retur
18、n自己的返回值這一情況外,還會(huì)導(dǎo)致某些異常被忽略。8.3 斷言斷言 Java異常機(jī)制的主要目的是保證程序的健壯性,而斷言是調(diào)試、測(cè)試程序的一種經(jīng)典方式。斷言失敗則拋出一個(gè)Error子類(lèi)AssertionError對(duì)象。斷言功能在Java 1.4中引入。8.3.1 斷言的語(yǔ)義和語(yǔ)法 斷言斷言(assertion)是有真值的陳述句。Java斷言的語(yǔ)義為:一個(gè)正確程序必須保證斷言句為真。如果程序執(zhí)行時(shí)計(jì)算它為false,則說(shuō)明程序已經(jīng)處于不正確的狀態(tài),系統(tǒng)將顯示某個(gè)警告或消息字符串并終止程序的執(zhí)行。 1. 斷言語(yǔ)句斷言語(yǔ)句 Java中斷言語(yǔ)句有兩種形式:assert anAssertion;asse
19、rt anAssertion: expression;anAssertion是一個(gè)boolean表達(dá)式。如果anAssertion的值為false,該語(yǔ)句將拋出一個(gè)AssertionError對(duì)象。2. 語(yǔ)法例子語(yǔ)法例子 package API.assertions;public class AssertionDemo private String name; private static char charAt(int index ,String s) assert !( index=s.length() :自己設(shè)計(jì)的private方法還瞎調(diào)用!真是佩服自己; return s.charAt
20、(index); public static void test(int index) String s = yqj2065; char c = charAt(index,s);/取 -1、2、7 System.out.println(c + is index +index+ of +s); assert false:如果前面沒(méi)有遇到AssertionError,輸入index-1; 3. 開(kāi)啟開(kāi)啟/關(guān)閉斷言功能關(guān)閉斷言功能 為了提高性能,默認(rèn)狀態(tài)下JVM關(guān)閉斷言功能。 要開(kāi)啟斷言功能,可以:含有斷言語(yǔ)句的Java程序編譯后,在控制臺(tái)中,以java -ea開(kāi)啟斷言功能。Java程序種調(diào)用Cla
21、ssLoader類(lèi)的若干方法,在程序運(yùn)行中動(dòng)態(tài)地開(kāi)啟和關(guān)閉斷言功能。為了學(xué)習(xí)的方便,BlueJ 3.0.8默認(rèn)狀態(tài)下打開(kāi)了斷言功能。 8.3.2 斷言的使用指南斷言的使用指南 斷言機(jī)制用于檢查程序的內(nèi)部正確性,不得干擾public方法的接口或替代其參數(shù)檢查。顯式地使用斷言,檢查一些關(guān)鍵的值(這些值對(duì)整個(gè)程序,或者局部功能的完成有很大的影響),以便于更容易地找到程序的錯(cuò)誤。斷言機(jī)制是調(diào)試、測(cè)試程序的一種經(jīng)典手段斷言機(jī)制是調(diào)試、測(cè)試程序的一種經(jīng)典手段。斷言的布爾表達(dá)式應(yīng)該短小、易懂。如果需要計(jì)算的表達(dá)式很復(fù)雜,應(yīng)該使用方法。斷言用于檢查程序運(yùn)行中的不變式(invariants)。不變式為程序運(yùn)行中
22、永遠(yuǎn)為真的條件。例如零和游戲中,一方所贏正是另一方所輸,游戲的總成績(jī)永遠(yuǎn)是零。斷言用于檢查方法的后置條件。 正方形正方形 is a 長(zhǎng)方形長(zhǎng)方形?public class Rectangle private double height; /高 private double width; /private double S;/面積S void setW(double w) width=w; void setH(double h) height=h; double getH() return height; double getW() return width; double getS() return height*width;double單純的單純的使用使用extends僅僅使用extends建立繼承關(guān)系,問(wèn)題是:1、 2、 Square繼承的height、width非常多余(想象一下在CAD/CAE程序中,成千上萬(wàn)的正方形對(duì)象的情景。大量浪費(fèi)內(nèi)存空間)?!静簧罹俊?、Square1不能夠替代Rectangle。不變式不變式 W = H Rectangle的se
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年麗水道路貨運(yùn)從業(yè)資格證模擬考試官方題下載
- 2025年石家莊貨運(yùn)資格證題庫(kù)在線練習(xí)
- 終止協(xié)議書(shū)范本范文6篇
- 《寶島臺(tái)灣》說(shuō)課稿
- 營(yíng)養(yǎng)強(qiáng)化劑競(jìng)爭(zhēng)策略分析報(bào)告
- 受托審計(jì)合同范本
- 原料冷庫(kù)租賃合同范例
- 衛(wèi)生間維修合同范本
- 臺(tái)球廳租賃合同范本
- 個(gè)人辭職申請(qǐng)書(shū)簡(jiǎn)短
- 二副工作心得體會(huì)實(shí)習(xí)感觸
- 土壤肥料全套課件
- 旅游消費(fèi)者行為學(xué)整套課件完整版電子教案課件匯總(最新)
- 學(xué)前兒童發(fā)展心理學(xué)(第3版-張永紅)教學(xué)課件1754
- 特氣供應(yīng)系統(tǒng)的規(guī)劃與設(shè)計(jì)
- 中職《機(jī)械基礎(chǔ)》全套課件(完整版)
- 勞技-中國(guó)結(jié)PPT通用課件
- 溫庭筠《望江南》ppt課件
- 口腔正畸學(xué)單詞
- 內(nèi)襯修復(fù)用HTPO管材企標(biāo)
- 部編教材一年級(jí)下冊(cè)生字筆順筆畫(huà)
評(píng)論
0/150
提交評(píng)論