捕獲或指定要求
有效的Java編程語言代碼必須遵守捕獲或指定需求,這意味著可能拋出某些異常的代碼必須包含以下任一項:
捕獲異常的try語句,try必須為異常提供處理程序,如捕獲和處理異常中所述。
一種方法,指定它可以拋出異常,該方法必須提供一個throws子句,列出異常,如通過方法拋出指定異常中所述。
不符合捕獲或指定要求的代碼將無法編譯。
并非所有異常都受捕獲或指定要求的約束,為了理解原因,我們需要查看三個基本類別的異常,其中只有一個受要求限制。
三種異常第一種異常是已檢查的異常,這些都是編寫良好的應用程序應該預料到并從中恢復的異常情況。例如,假設應用程序提示用戶輸入文件名,然后通過將名稱傳遞給java.io.FileReader的構造函數來打開該文件,通常,用戶提供現有可讀文件的名稱,因此FileReader構造對象成功,并且應用程序的執行正常進行。但有時用戶提供不存在的文件的名稱,構造函數拋出java.io.FileNotFoundException,一個編寫良好的程序將捕獲此異常并通知用戶該錯誤,可能提示更正的文件名。
已檢查的異常情況受捕獲或指定要求的約束,除Error、RuntimeException及其子類表示的異常外,所有異常都是經過檢查的異常。
第二種異常是錯誤,這些是應用程序外部的異常情況,應用程序通常無法預測或恢復。例如,假設應用程序對于輸入成功打開文件,但由于硬件或系統故障而無法讀取文件,不成功的讀取將拋出java.io.IOError,應用程序可能會選擇捕獲此異常,以便通知用戶該問題 — 但是程序打印堆棧跟蹤并退出也可能有意義。
錯誤不受捕獲或指定要求的約束,錯誤是Error及其子類表示的異常。
第三種異常是運行時異常,這些是應用程序內部的異常情況,應用程序通常無法預測或恢復,這些通常表示編程bug,例如邏輯錯誤或API的不當使用。例如,考慮前面描述的應用程序將文件名傳遞給FileReader的構造函數,如果邏輯錯誤導致將null傳遞給構造函數,則構造函數將拋出NullPointerException,應用程序可以捕獲此異常,但消除導致異常發生的bug可能更有意義。
運行時異常不受捕獲或指定要求的約束,運行時異常是RuntimeException及其子類表示的異常。
錯誤和運行時異常統稱為未經檢查的異常。
通過方法拋出指定異常有時,代碼可以捕獲可能在其中發生的異常,但是,在其他情況下,最好讓調用堆棧中進一步的方法處理異常。例如,如果你將ListOfNumbers類作為類包的一部分提供,則可能無法預測包的所有用戶的需求,在這種情況下,最好不捕獲異常并允許調用堆棧進一步的方法來處理它。
如果writeList方法沒有捕獲可能在其中發生的已檢查異常,則writeList方法必須指定它可以拋出這些異常,讓我們修改原始的writeList方法來指定它可以拋出而不是捕獲它們的異常,這是不能編譯的writeList方法的原始版本。
public void writeList() { PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt")); for (int i = 0; i < SIZE; i++) { out.println("Value at: " + i + " = " + list.get(i)); } out.close(); }
要指定writeList可以拋出兩個異常,請將throws子句添加到writeList方法的方法聲明中,throws子句包含throws關鍵字,后跟逗號分隔的該方法拋出的所有異常列表,該子句在方法名稱和參數列表之后以及定義方法范圍的大括號之前,這是一個例子。
public void writeList() throws IOException, IndexOutOfBoundsException {
請記住,IndexOutOfBoundsException是未經檢查的異常,在throws子句中包含它不是強制性的,你可以僅寫下面的內容。
public void writeList() throws IOException {繞過捕獲或指定
一些程序員認為捕獲或指定要求是異常機制中的一個嚴重缺陷,并通過使用未經檢查的異常代替已檢查的異常來繞過它,通常,不建議這樣做,未經檢查的異常 — 爭議部分討論何時適合使用未經檢查的異常。
未經檢查的異常 — 爭議因為Java編程語言不需要捕獲或指定未經檢查的異常的方法(RuntimeException、Error及其子類),程序員可能會試圖編寫只拋出未經檢查的異常的代碼,或者讓所有異常子類繼承自RuntimeException,這兩個快捷方式都允許程序員編寫代碼而不必擔心編譯器錯誤,也不必費心去指定或捕獲任何異常。雖然這對程序員來說似乎很方便,但它會回避catch的意圖或指定要求,并且可能會導致其他人使用你的類時出現問題。
為什么設計人員決定強制一個方法指定可以在其范圍內拋出的所有未捕獲的已檢查異常?方法可以拋出的任何Exception都是該方法的公共編程接口的一部分,那些調用方法的人必須知道方法可以拋出的異常,以便他們可以決定如何處理它們,這些異常與該方法的編程接口一樣,也是其參數和返回值的一部分。
下一個問題可能是:“如果記錄方法的API非常好,包括它可以拋出的異常,為什么不指定運行時異常呢?”,運行時異常表示編程問題導致的問題,因此,無法合理地期望API客戶端代碼從它們恢復或以任何方式處理它們,這些問題包括算術異常,例如除以零;指針異常,例如嘗試通過空引用訪問對象;索引異常,例如嘗試通過索引太大或太小來訪問數組元素。
運行時異常可以在程序中的任何地方發生,而在典型的程序中,它們可以非常多,必須在每個方法聲明中添加運行時異常會降低程序的清晰度,因此,編譯器不要求你捕獲或指定運行時異常(盡管你可以)。
拋出RuntimeException的常見做法之一是用戶錯誤地調用方法,例如,方法可以檢查其中一個參數是否錯誤地為null,如果參數為null,則該方法可能會拋出NullPointerException,這是一個未經檢查的異常。
一般來說,不要因為你不希望指定方法可以拋出的異常而煩惱而拋出RuntimeException或創建RuntimeException的子類。
這是底線指南:如果可以合理地期望客戶端從異常中恢復,則將其作為已檢查的異常,如果客戶端無法執行任何操作以從異常中恢復,請將其設置為未經檢查的異常。
上一篇:什么是異常? 下一篇:捕獲和處理異常文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74024.html
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實踐沒有利用在后續版本中引入的改進。 Java教程是希望使用Java編程語言創建應用程序的程序員的實用指南,其中包括數百個完整的工作示例和數十個課程,相關課程組被組織成教程。 覆蓋基礎知識的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購買。 入門 介紹Java技術和安裝Java開發軟件并使用...
什么是異常? exception一詞是exceptional event這一短語的簡寫。 定義:異常是在程序執行期間發生的事件,它會破壞程序指令的正常流程。 當方法中發生錯誤時,該方法會創建一個對象并將其交給運行時系統,該對象稱為異常對象,包含有關錯誤的信息,包括錯誤發生時的類型和程序狀態,創建異常對象并將其交給運行時系統稱為拋出異常。 在方法拋出異常后,運行時系統會嘗試查找處理它的內容,處理異常...
捕獲和處理異常 本節描述如何使用三個異常處理程序組件 — try、catch和finally塊 — 來編寫異常處理程序,然后,解釋了Java SE 7中引入的try-with-resources語句,try-with-resources語句特別適用于使用Closeable資源的情況,例如流。 本節的最后一部分將介紹一個示例,并分析各種場景中發生的情況。 以下示例定義并實現名為ListOfNumbe...
Thread對象 每個線程都與Thread類的實例相關聯,使用Thread對象創建并發應用程序有兩種基本策略。 要直接控制線程的創建和管理,只需在每次應用程序需要啟動異步任務時實例化Thread。 要從應用程序的其余部分抽象線程管理,請將應用程序的任務傳遞給執行器。 本節介紹Thread對象的使用,Executors將與其他高級并發對象一起討論。 定義和啟動線程 創建Thread實例的應用程序...
如何拋出異常 在捕獲異常之前,某些代碼必須拋出一個,任何代碼都可能拋出異常:你的代碼,來自其他人編寫的包中的代碼,例如Java平臺附帶的包或Java運行時環境,無論拋出什么異常,它總是使用throw語句拋出。 你可能已經注意到,Java平臺提供了許多異常類,所有類都是Throwable類的后代,并且所有類都允許程序區分在程序執行期間可能發生的各種類型的異常。 你還可以創建自己的異常類來表示你編寫的...
閱讀 1198·2021-11-10 11:35
閱讀 2925·2021-09-24 10:35
閱讀 2957·2021-09-22 15:38
閱讀 2807·2019-08-30 15:43
閱讀 1338·2019-08-29 18:39
閱讀 2558·2019-08-29 15:22
閱讀 2789·2019-08-28 18:17
閱讀 612·2019-08-26 13:37