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