如何拋出異常
在捕獲異常之前,某些代碼必須拋出一個(gè),任何代碼都可能拋出異常:你的代碼,來自其他人編寫的包中的代碼,例如Java平臺(tái)附帶的包或Java運(yùn)行時(shí)環(huán)境,無論拋出什么異常,它總是使用throw語句拋出。
你可能已經(jīng)注意到,Java平臺(tái)提供了許多異常類,所有類都是Throwable類的后代,并且所有類都允許程序區(qū)分在程序執(zhí)行期間可能發(fā)生的各種類型的異常。
你還可以創(chuàng)建自己的異常類來表示你編寫的類中可能出現(xiàn)的問題,實(shí)際上,如果你是程序包開發(fā)人員,則可能必須創(chuàng)建自己的一組異常類,以允許用戶將程序包中可能發(fā)生的錯(cuò)誤與Java平臺(tái)或其他程序包中發(fā)生的錯(cuò)誤區(qū)分開來。
你還可以創(chuàng)建鏈?zhǔn)疆惓#嘘P(guān)更多信息,請(qǐng)參閱“鏈?zhǔn)疆惓!辈糠帧?/p> throw語句
所有方法都使用throw語句拋出異常,throw語句需要一個(gè)參數(shù):一個(gè)throwable對(duì)象,Throwable對(duì)象是Throwable類的任何子類的實(shí)例,這是一個(gè)throw語句的例子。
throw someThrowableObject;
讓我們看一下上下文中的throw語句,以下pop方法取自實(shí)現(xiàn)公共堆棧對(duì)象的類,該方法從堆棧中刪除頂部元素并返回該對(duì)象。
public Object pop() { Object obj; if (size == 0) { throw new EmptyStackException(); } obj = objectAt(size - 1); setObjectAt(size - 1, null); size--; return obj; }
pop方法檢查堆棧上是否有任何元素,如果堆棧為空(其大小等于0),則pop實(shí)例化一個(gè)新的EmptyStackException對(duì)象(java.util的成員)并拋出它,本章中的創(chuàng)建異常類部分介紹了如何創(chuàng)建自己的異常類,現(xiàn)在,你需要記住的是,你只能拋出從java.lang.Throwable類繼承的對(duì)象。
請(qǐng)注意,pop方法的聲明不包含throws子句,EmptyStackException不是已檢查的異常,因此不需要pop來聲明它可能發(fā)生。
Throwable類及其子類從Throwable類繼承的對(duì)象包括直接后代(直接從Throwable類繼承的對(duì)象)和間接后代(從Throwable類的子級(jí)或?qū)O級(jí)繼承的對(duì)象),下圖說明了Throwable類的類層次結(jié)構(gòu)及其最重要的子類,如你所見,Throwable有兩個(gè)直接后代:Error和Exception。
Error類當(dāng)發(fā)生Java虛擬機(jī)中的動(dòng)態(tài)鏈接故障或其他硬故障時(shí),虛擬機(jī)拋出Error,簡單程序通常不會(huì)捕獲或拋出Errors。
Exception類大多數(shù)程序拋出并捕獲從Exception類派生的對(duì)象,Exception表示發(fā)生了問題,但這不是一個(gè)嚴(yán)重的系統(tǒng)問題,你編寫的大多數(shù)程序?qū)伋霾⒉东@Exception而不是Error。
Java平臺(tái)定義了Exception類的許多后代,這些后代表示可能發(fā)生的各種類型的異常。例如,IllegalAccessException表示無法找到特定方法,NegativeArraySizeException表示程序試圖創(chuàng)建負(fù)大小的數(shù)組。
一個(gè)Exception子類RuntimeException保留用于指示錯(cuò)誤使用API??的異常,運(yùn)行時(shí)異常的一個(gè)示例是NullPointerException,當(dāng)方法嘗試通過空引用訪問對(duì)象的成員時(shí)發(fā)生,未經(jīng)檢查的異常 — 爭議部分討論了為什么大多數(shù)應(yīng)用程序不應(yīng)拋出運(yùn)行時(shí)異?;?b>RuntimeException子類。
鏈?zhǔn)疆惓?/b>應(yīng)用程序通常會(huì)通過拋出另一個(gè)異常來響應(yīng)異常,實(shí)際上,第一個(gè)異常導(dǎo)致第二個(gè)異常,了解一個(gè)異常何時(shí)導(dǎo)致另一個(gè)異常非常有用,鏈?zhǔn)疆惓S兄诔绦騿T執(zhí)行此操作。
以下是Throwable中支持鏈?zhǔn)疆惓5姆椒ê蜆?gòu)造函數(shù)。
Throwable getCause() Throwable initCause(Throwable) Throwable(String, Throwable) Throwable(Throwable)
initCause和Throwable構(gòu)造函數(shù)的Throwable參數(shù)是導(dǎo)致當(dāng)前異常的異常,getCause返回導(dǎo)致當(dāng)前異常的異常,initCause設(shè)置當(dāng)前異常的原因。
以下示例顯示如何使用鏈?zhǔn)疆惓!?/p>
try { } catch (IOException e) { throw new SampleException("Other IOException", e); }
在此示例中,捕獲IOException時(shí),會(huì)創(chuàng)建一個(gè)新的SampleException異常,并附加原始原因,并將異常鏈拋出到下一個(gè)更高級(jí)別的異常處理程序。
訪問堆棧跟蹤信息現(xiàn)在讓我們假設(shè)更高級(jí)別的異常處理程序想要以自己的格式轉(zhuǎn)儲(chǔ)堆棧跟蹤。
定義:堆棧跟蹤提供有關(guān)當(dāng)前線程的執(zhí)行歷史記錄的信息,并列出在發(fā)生異常時(shí)調(diào)用的類和方法的名稱,堆棧跟蹤是一種有用的調(diào)試工具,通常在拋出異常時(shí)可以利用它。
以下代碼顯示如何在異常對(duì)象上調(diào)用getStackTrace方法。
catch (Exception cause) { StackTraceElement elements[] = cause.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { System.err.println(elements[i].getFileName() + ":" + elements[i].getLineNumber() + ">> " + elements[i].getMethodName() + "()"); } }Logging API
下一個(gè)代碼段記錄catch塊中發(fā)生異常的位置,但是,它不是手動(dòng)解析堆棧跟蹤并將輸出發(fā)送到System.err(),而是使用java.util.logging包中的日志記錄工具將輸出發(fā)送到文件。
try { Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); } catch (IOException e) { Logger logger = Logger.getLogger("package.name"); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { logger.log(Level.WARNING, elements[i].getMethodName()); } }創(chuàng)建異常類
當(dāng)面對(duì)選擇要拋出的異常類型時(shí),你可以使用其他人編寫的異常 — Java平臺(tái)提供了許多可以使用的異常類 — 或者你可以編寫自己的異常類,如果你對(duì)以下任何問題的回答是肯定的,你應(yīng)該編寫自己的異常類;否則,你可能會(huì)使用別人的。
你是否需要Java平臺(tái)中未表示的異常類型?
如果他們可以將你的異常與其他供應(yīng)商編寫的類別所引發(fā)的異常區(qū)分開來,它會(huì)幫助用戶嗎?
你的代碼是否會(huì)拋出多個(gè)相關(guān)的異常?
如果你使用其他人的異常,用戶是否可以訪問這些異常?一個(gè)類似的問題是,你的包是否應(yīng)該獨(dú)立且自包含?
一個(gè)例子假設(shè)你正在編寫鏈表類,該類支持以下方法,其中包括:
objectAt(int n) — 返回列表中第n個(gè)位置的對(duì)象,如果參數(shù)小于0或大于列表中當(dāng)前對(duì)象的數(shù)量,則引發(fā)異常。
firstObject() — 返回列表中的第一個(gè)對(duì)象,如果列表不包含任何對(duì)象,則拋出異常。
indexOf(Object o) — 在列表中搜索指定的Object并返回其在列表中的位置,如果傳遞給方法的對(duì)象不在列表中,則拋出異常。
鏈表類可以拋出多個(gè)異常,并且能夠通過一個(gè)異常處理程序捕獲鏈表所引發(fā)的所有異常會(huì)很方便,此外,如果你計(jì)劃在包中分發(fā)鏈表,則應(yīng)將所有相關(guān)代碼打包在一起,因此,鏈表應(yīng)該提供自己的一組異常類。
下圖說明了鏈表拋出的異常的一個(gè)可能的類層次結(jié)構(gòu)。
選擇超類任何Exception子類都可以用作LinkedListException的父類,但是,快速瀏覽這些子類就會(huì)發(fā)現(xiàn)它們不合適,因?yàn)樗鼈兲珜I(yè)化或與LinkedListException完全無關(guān),因此,LinkedListException的父類應(yīng)該是Exception。
你編寫的大多數(shù)applet和應(yīng)用程序都會(huì)拋出Exception對(duì)象,Error通常用于系統(tǒng)中嚴(yán)重的硬錯(cuò)誤,例如阻止JVM運(yùn)行的錯(cuò)誤。
對(duì)于可讀代碼,最好將字符串Exception附加到從Exception類繼承(直接或間接)的所有類的名稱。上一篇:捕獲和處理異常
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77477.html
捕獲和處理異常 本節(jié)描述如何使用三個(gè)異常處理程序組件 — try、catch和finally塊 — 來編寫異常處理程序,然后,解釋了Java SE 7中引入的try-with-resources語句,try-with-resources語句特別適用于使用Closeable資源的情況,例如流。 本節(jié)的最后一部分將介紹一個(gè)示例,并分析各種場景中發(fā)生的情況。 以下示例定義并實(shí)現(xiàn)名為ListOfNumbe...
異常的優(yōu)點(diǎn) 現(xiàn)在你已經(jīng)知道了什么是異常以及如何使用它們,現(xiàn)在是時(shí)候了解在程序中使用異常的優(yōu)勢(shì)了。 優(yōu)點(diǎn)1:將錯(cuò)誤處理代碼與常規(guī)代碼分開 異常提供了從程序的主邏輯中分離異常發(fā)生時(shí)應(yīng)該做什么的細(xì)節(jié)的方法,在傳統(tǒng)的編程中,錯(cuò)誤檢測、報(bào)告和處理通常會(huì)導(dǎo)致混亂的意大利面代碼,例如,考慮這里的偽代碼方法將整個(gè)文件讀入內(nèi)存。 readFile { open the file; determine...
捕獲或指定要求 有效的Java編程語言代碼必須遵守捕獲或指定需求,這意味著可能拋出某些異常的代碼必須包含以下任一項(xiàng): 捕獲異常的try語句,try必須為異常提供處理程序,如捕獲和處理異常中所述。 一種方法,指定它可以拋出異常,該方法必須提供一個(gè)throws子句,列出異常,如通過方法拋出指定異常中所述。 不符合捕獲或指定要求的代碼將無法編譯。 并非所有異常都受捕獲或指定要求的約束,為了理解原因,...
摘要:挺多人咨詢的,異常處理用切面注解去實(shí)現(xiàn)去全局異常處理。全局異常處理類,代碼如下代碼解析如下抽象類是用來處理全局錯(cuò)誤時(shí)進(jìn)行擴(kuò)展和實(shí)現(xiàn)注解標(biāo)記的切面排序,值越小擁有越高的優(yōu)先級(jí),這里設(shè)置優(yōu)先級(jí)偏高。 本文內(nèi)容 為什么要全局異常處理? WebFlux REST 全局異常處理實(shí)戰(zhàn) 小結(jié) 摘錄:只有不斷培養(yǎng)好習(xí)慣,同時(shí)不斷打破壞習(xí)慣,我們的行為舉止才能夠自始至終都是正確的。 一、為什么要全局...
摘要:無需檢查的異常也是的子類。從低層拋出的需檢查異常強(qiáng)制要求調(diào)用方捕獲或是拋出該異常。當(dāng)前執(zhí)行的線程將會(huì)停止并報(bào)告該異常。單元測試允許我在使用中查看異常,并且作為一個(gè)可以被執(zhí)行的文檔來使用。不要捕獲最高層異常繼承的異常同樣是的子類。 前言 異常處理的問題之一是知道何時(shí)以及如何去使用它。我會(huì)討論一些異常處理的最佳實(shí)踐,也會(huì)總結(jié)最近在異常處理上的一些爭論。 作為程序員,我們想要寫高質(zhì)量的能夠解...
閱讀 2114·2021-09-22 15:54
閱讀 1863·2021-09-04 16:40
閱讀 891·2019-08-30 15:56
閱讀 2654·2019-08-30 15:44
閱讀 2174·2019-08-30 13:52
閱讀 1148·2019-08-29 16:35
閱讀 3370·2019-08-29 16:31
閱讀 2595·2019-08-29 13:48