[英]What is the value of letting an exception move up the call stack?
我只是在閱讀有關try-catch blocks
和異常處理的信息,而我在“ Profgating IOExceptions”一節中看到的內容使我有些困惑。 詹科夫說,如果方法C引發IOException
public void MethC() throws IOException{}
-但沒有try-catch
來處理它,它將調用堆棧匯總到可能具有try-catch
的調用方法處理異常
try-catch-finally
塊的全部目的似乎是要處理一個異常,該異常將被處理,從而使您的程序崩潰,對嗎? 那么,為什么還要讓異常將調用堆棧回滾到鏈上某處的try-catch
呢? 有什么價值? 如果有的話,在我看來,讓異常繞過鏈條,而不是立即處理它,只會損害程序並形成不良形式,並導致效率低下或效率低下。
只要您的設計有必要,讓異常遍及整個調用棧就可以了。 一個簡單的示例是,如果您的main
方法在可能具有非常深的調用堆棧的調用周圍具有try
/ catch
塊。 如果錯誤發生在任何時候,它可以throw
一個異常,程序可與正常結束catch
的main
說法:“對不起,下面的錯誤時拋出發生,所以程序已經結束”。
永遠不要捕獲異常並讓程序異常終止是不好的設計,但是如果在實例中有意義的話,從實際異常發生的地方將其捕獲很多級別是沒有錯的。
通常,問題深深地發生在代碼中,正確的處理方式(顯示對話框?打印錯誤?安靜地處理?)在不同的調用路徑中可能有所不同,可以在其他地方進行選擇調用堆棧。
通常,應在能夠處理異常的調用堆棧中的位置處處理異常。
例如,假設您有一個庫方法,該方法采用文件路徑並以byte[]
返回文件的全部內容:
public static byte[] readFile(final String filePath) throws IOException {
final InputStream inputStream = new FileInputStream(filePath);
...
}
此函數無法“處理”不存在的文件。 如果new FileInputStream(filePath)
引發FileNotFoundException
(這是IOException
的子類型),則此函數可以做的最好的事情是通知其調用者。 調用者具有有關filePath
來源以及文件丟失的含義的更多信息。 例如,如果filePath
是由用戶鍵入的,則可能意味着程序需要向用戶顯示一條消息,以使他/她知道可能是拼寫錯誤。 關鍵是, readFile
沒有這些信息,也無法做出正確的決定。 因此,它應該讓異常傳播給可以的調用者。
try-catch-finally
塊的全部目的似乎是要處理一個異常,該異常將被處理,從而使您的程序崩潰,對嗎?
不完全是。 異常並不總是會導致程序崩潰,它可能只是“導致”程序的某些部分無法正常工作。 確實使用try-catch-finally
來處理異常。
為什么讓異常將調用堆棧回滾到鏈上某處的try-catch? 有什么價值?
因為有時發生異常的方法不適合決定如何處理它。
我舉一個例子:看一下Integer.parseInt(String s)
,它接受一個String
並嘗試根據其內容將其轉換為int
。 由於此操作是在運行時完成的,因此您無法提前知道該字符串是什么,因此必須考慮該字符串不是數字,例如,如果它來自用戶輸入。 如果它不是可分析的字符串,那么您希望該方法如何處理它? 為什么要決定它原本不打算執行的操作的結果?
這就是為什么該方法引發NumberFormatException - if the string does not contain a parsable integer
。 調用該方法的人都有范圍來決定應該做什么,因為該方法專用於將字符串轉換為數字。 它可以因為最后一個無效而要求輸入新字符串,也可以僅使用默認數字作為占位符。
一個真實的類比:老板告訴他的秘書在給定的日期安排與該雇員的會議,秘書發現該雇員在該日期休假。 秘書應該自己處理這種情況嗎? 可能不是。 相反,他們會按照“ InvalidMeetingTime”的方式向老板“拋出異常”,然后讓老板決定要做什么。
在我看來,讓異常繞過鏈條,而不是立即處理它,只會損害程序,並且格式不好,導致效率低下或效率低下。
這就是調用范圍負責正確委派事件的原因。 要么自己處理它,要么向上傳遞它,直到有東西可以處理為止。
請參閱“ 課程:例外”中的更多內容 。
有時,由於多種原因(服務,Restfull API等),讓異常回滾到堆棧會很有幫助。 假設您有一個顯示或解析文件並將文件名作為參數的方法,您不知道誰將使用您的方法或用於什么目的,因此拋出異常會給開發人員另一個機會顯示他的消息或句柄如他所願。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.