異常的優(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ò)誤檢測(cè)、報(bào)告和處理通常會(huì)導(dǎo)致混亂的意大利面代碼,例如,考慮這里的偽代碼方法將整個(gè)文件讀入內(nèi)存。
readFile { open the file; determine its size; allocate that much memory; read the file into memory; close the file; }
乍一看,這個(gè)功能似乎很簡(jiǎn)單,但它忽略了以下所有潛在的錯(cuò)誤。
如果無法打開文件會(huì)怎么樣?
如果無法確定文件的長(zhǎng)度會(huì)發(fā)生什么?
如果無法分配足夠的內(nèi)存會(huì)怎樣?
如果讀取失敗會(huì)發(fā)生什么?
如果文件無法關(guān)閉會(huì)發(fā)生什么?
要處理此類情況,readFile函數(shù)必須具有更多代碼才能執(zhí)行錯(cuò)誤檢測(cè)、報(bào)告和處理,下面是一個(gè)函數(shù)的例子。
errorCodeType readFile { initialize errorCode = 0; open the file; if (theFileIsOpen) { determine the length of the file; if (gotTheFileLength) { allocate that much memory; if (gotEnoughMemory) { read the file into memory; if (readFailed) { errorCode = -1; } } else { errorCode = -2; } } else { errorCode = -3; } close the file; if (theFileDidntClose && errorCode == 0) { errorCode = -4; } else { errorCode = errorCode and -4; } } else { errorCode = -5; } return errorCode; }
這里有很多錯(cuò)誤檢測(cè)、報(bào)告和返回,原始的七行代碼在雜亂中丟失了,更糟糕的是,代碼的邏輯流程也已丟失,因此很難判斷代碼是否正在做正確的事情:如果函數(shù)無法分配足夠的內(nèi)存,文件是否真的被關(guān)閉?在編寫方法三個(gè)月后修改方法時(shí),確保代碼繼續(xù)做正確的事情變得更加困難,許多程序員通過忽略它來解決這個(gè)問題 — 當(dāng)程序崩潰時(shí)會(huì)報(bào)告錯(cuò)誤。
異常使你能夠編寫代碼的主流程,并在其他地方處理異常情況,如果readFile函數(shù)使用異常而不是傳統(tǒng)的錯(cuò)誤管理技術(shù),那么它看起來更像是以下內(nèi)容。
readFile { try { open the file; determine its size; allocate that much memory; read the file into memory; close the file; } catch (fileOpenFailed) { doSomething; } catch (sizeDeterminationFailed) { doSomething; } catch (memoryAllocationFailed) { doSomething; } catch (readFailed) { doSomething; } catch (fileCloseFailed) { doSomething; } }
請(qǐng)注意,異常不會(huì)使你無需執(zhí)行檢測(cè)、報(bào)告和處理錯(cuò)誤的工作,但它們確實(shí)可以幫助你更有效地組織工作。
優(yōu)點(diǎn)2:在調(diào)用堆棧中傳播錯(cuò)誤異常的第二個(gè)優(yōu)點(diǎn)是能夠在方法的調(diào)用堆棧中傳播錯(cuò)誤報(bào)告,假設(shè)readFile方法是主程序進(jìn)行的一系列嵌套方法調(diào)用中的第四個(gè)方法:method1調(diào)用method2,它調(diào)用method3,最后調(diào)用readFile。
method1 { call method2; } method2 { call method3; } method3 { call readFile; }
假設(shè)method1是唯一對(duì)readFile中可能發(fā)生的錯(cuò)誤感興趣的方法,傳統(tǒng)的錯(cuò)誤通知技術(shù)強(qiáng)制method2和method3將readFile返回的錯(cuò)誤代碼傳播到調(diào)用堆棧,直到錯(cuò)誤代碼最終到達(dá)method1 — 唯一感興趣的方法。
method1 { errorCodeType error; error = call method2; if (error) doErrorProcessing; else proceed; } errorCodeType method2 { errorCodeType error; error = call method3; if (error) return error; else proceed; } errorCodeType method3 { errorCodeType error; error = call readFile; if (error) return error; else proceed; }
回想一下,Java運(yùn)行時(shí)環(huán)境在調(diào)用堆棧中向后搜索,以查找對(duì)處理特定異常感興趣的任何方法,一個(gè)方法可以避開在其中拋出的任何異常,從而允許調(diào)用堆棧上更遠(yuǎn)的方法捕獲它,因此,只有關(guān)心錯(cuò)誤的方法才擔(dān)心檢測(cè)錯(cuò)誤。
method1 { try { call method2; } catch (exception e) { doErrorProcessing; } } method2 throws exception { call method3; } method3 throws exception { call readFile; }
但是,正如偽代碼所示,避開異常需要中間方法的一些作用,必須在其throws子句中指定可以在方法中拋出的任何已檢查異常。
優(yōu)點(diǎn)3:分組和區(qū)分錯(cuò)誤類型因?yàn)樵诔绦蛑袙伋龅乃挟惓6际菍?duì)象,所以異常的分組或分類是類層次結(jié)構(gòu)的自然結(jié)果,Java平臺(tái)中的一組相關(guān)異常類的示例是在java.io中定義的 — IOException及其后代。IOException是最常見的,表示執(zhí)行I/O時(shí)可能發(fā)生的任何類型的錯(cuò)誤,它的后代表示更具體的錯(cuò)誤,例如,FileNotFoundException意味著文件沒在磁盤上。
方法可以編寫可以處理非常特定異常的特定處理程序,FileNotFoundException類沒有后代,因此以下處理程序只能處理一種類型的異常。
catch (FileNotFoundException e) { ... }
方法可以通過在catch語句中指定任何異常的超類來基于其組或常規(guī)類型捕獲異常,例如,要捕獲所有I/O異常,無論其具體類型如何,異常處理程序都會(huì)指定IOException參數(shù)。
catch (IOException e) { ... }
此處理程序?qū)⒛軌虿东@所有I/O異常,包括FileNotFoundException、EOFException等,你可以通過查詢傳遞給異常處理程序的參數(shù)來查找有關(guān)所發(fā)生情況的詳細(xì)信息,例如,使用以下命令打印堆棧跟蹤。
catch (IOException e) { // Output goes to System.err. e.printStackTrace(); // Send trace to stdout. e.printStackTrace(System.out); }
你甚至可以設(shè)置一個(gè)異常處理程序來處理任何Exception。
// A (too) general exception handler catch (Exception e) { ... }
Exception類接近Throwable類層次結(jié)構(gòu)的頂部,因此,除了處理程序要捕獲的那些異常之外,此處理程序還將捕獲許多其他異常。如果你希望程序執(zhí)行所有操作,你可能希望以這種方式處理異常,例如,為用戶打印出錯(cuò)誤消息然后退出。
但是,在大多數(shù)情況下,你希望異常處理程序盡可能具體,原因是,處理程序必須做的第一件事是確定發(fā)生了什么類型的異常,然后才能決定最佳的恢復(fù)策略。實(shí)際上,通過不捕獲特定錯(cuò)誤,處理程序必須適應(yīng)任何可能性,過于通用的異常處理程序通過捕獲和處理程序員沒有預(yù)料到的異常,以及處理程序沒有打算處理的異常,可以使代碼更容易出錯(cuò)。
如上所述,你可以創(chuàng)建異常組并以一般方式處理異常,或者你可以使用特定的異常類型來區(qū)分異常并以精確的方式處理異常。
總結(jié)程序可以使用異常來指示發(fā)生了錯(cuò)誤,要拋出異常,請(qǐng)使用throw語句并為其提供異常對(duì)象 — Throwable的后代 — 以提供有關(guān)發(fā)生的特定錯(cuò)誤的信息,拋出未捕獲的已檢查異常的方法必須在其聲明中包含throws子句。
程序可以通過結(jié)合使用try、catch和finally塊來捕獲異常。
try塊標(biāo)識(shí)可能發(fā)生異常的代碼塊。
catch塊標(biāo)識(shí)一個(gè)代碼塊,稱為異常處理程序,可以處理特定類型的異常。
finally塊標(biāo)識(shí)了一個(gè)保證執(zhí)行的代碼塊,它是關(guān)閉文件、恢復(fù)資源以及在try塊中包含代碼之后進(jìn)行清理的正確位置。
try語句應(yīng)包含至少一個(gè)catch塊或finally塊,并且可能有多個(gè)catch塊。
異常對(duì)象的類指示拋出的異常類型,異常對(duì)象可以包含有關(guān)錯(cuò)誤的更多信息,包括錯(cuò)誤消息,使用鏈?zhǔn)疆惓r(shí),異??梢灾赶?qū)е庐惓5漠惓?,異常又可以指向?qū)е滤漠惓?,依此類推?/p> 上一篇:如何拋出異常 下一篇:I/O流
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77555.html
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實(shí)踐沒有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購買。 入門 介紹Java技術(shù)和安裝Java開發(fā)軟件并使用...
摘要:框架最初是由編寫的,并且年月首次在許可下發(fā)布。在一個(gè)方法執(zhí)行之后,只有在方法退出拋出異常時(shí),才能執(zhí)行通知在建議方法調(diào)用之前和之后,執(zhí)行通知。方法執(zhí)行之后,不考慮其結(jié)果,執(zhí)行通知。 導(dǎo)讀: 在上篇文章的結(jié)尾提到了Spring Boot 提供了一系列的框架整合(Starter POMs)幫助我們提升開發(fā)效率,但是這并不意味著我們不需要學(xué)習(xí)這些框架,反而更需要去學(xué)習(xí),通過學(xué)習(xí)這些框架可以使...
摘要:年月宣布支持時(shí)間延長(zhǎng)到年。更詳細(xì)的發(fā)布列表參閱官網(wǎng)的版本號(hào)分為三段,形如。其中表示大版本號(hào),一般當(dāng)整體重寫,或出現(xiàn)不向后兼容的改變時(shí),增加表示功能更新,出現(xiàn)新功能時(shí)增加表示小的改動(dòng)如修復(fù)了某個(gè),只要有修改就增加。年公司正式發(fā)布。 < 返回索引頁 Python語言簡(jiǎn)介 Python介紹及發(fā)展 介紹 Python 官方網(wǎng)站:https://www.python.org/, 大家可以到此處下...
摘要:無需檢查的異常也是的子類。從低層拋出的需檢查異常強(qiáng)制要求調(diào)用方捕獲或是拋出該異常。當(dāng)前執(zhí)行的線程將會(huì)停止并報(bào)告該異常。單元測(cè)試允許我在使用中查看異常,并且作為一個(gè)可以被執(zhí)行的文檔來使用。不要捕獲最高層異常繼承的異常同樣是的子類。 前言 異常處理的問題之一是知道何時(shí)以及如何去使用它。我會(huì)討論一些異常處理的最佳實(shí)踐,也會(huì)總結(jié)最近在異常處理上的一些爭(zhēng)論。 作為程序員,我們想要寫高質(zhì)量的能夠解...
閱讀 1256·2023-04-26 00:47
閱讀 3601·2021-11-16 11:53
閱讀 824·2021-10-08 10:05
閱讀 2784·2021-09-22 15:19
閱讀 3002·2019-08-30 15:55
閱讀 2780·2019-08-29 16:55
閱讀 2960·2019-08-29 15:20
閱讀 1133·2019-08-23 16:13