在什麼情況下應該在應用程序上捕獲java.lang.Error
?何時捕獲java.lang.Error?
回答
一般情況下,從不。 但是,有時您需要捕獲特定的錯誤。
如果你正在編寫framework-ish代碼(加載第三方類),那麼趕上LinkageErrors(沒有找到類def,不滿意的鏈接,不兼容的類改變)可能是明智的。 我也看到了一些愚蠢的第三方代碼拋出錯誤sublcasses,所以你將不得不處理這些。
順便說一下,我不確定無法從OutOfMemory恢復。
幾乎從不。錯誤被設計爲應用程序通常無法做到的任何問題。唯一的例外可能是處理錯誤的表示,但即使這樣也可能不會按計劃進行,具體取決於錯誤。
從來沒有。您永遠無法確定應用程序是否能夠執行下一行代碼。如果你得到OutOfMemoryError
,你有no guarantee that you will be able to do anything reliably。捕獲RuntimeException並檢查異常,但從不錯誤。
永不言敗。我們已經測試了代碼「確定錯誤」;然後捕獲AssertionError以確保設置了-ea標誌。 除此之外...是的,可能永遠不會;-) – 2008-12-09 14:52:43
如何將請求傳遞給工作線程的服務器應用程序。在工作者線程上捕獲Throwable來捕獲任何錯誤並且至少嘗試並記錄出錯的情況可能沒有意義。 – Leigh 2008-12-09 16:11:35
永遠......除非你絕對需要。從來沒有一個強大的詞,總是有例外的規則。如果你正在構建一個框架,即使只是記錄日誌,你也不一定要捕捉和處理某些錯誤。 – Robin 2008-12-09 19:49:56
而且有一對夫婦的地方,如果你趕上一個錯誤等情況下,你必須重新拋出。例如ThreadDeath不應該被抓住,它可能會導致大問題是你抓住它在一個封閉的環境(如應用服務器):
應用程序應抓住這一類的實例只有當它必須清理 在異步終止之後。如果ThreadDeath被方法捕獲, 重新執行它是非常重要的,以便線程真正死亡。
這實際上是一個非問題,因爲你只是*不*捕獲`錯誤`。 – Bombe 2008-12-09 14:37:36
很少。
我只會說在線程的頂級水平,以便嘗試發出線程死亡原因的消息。
如果你在一個爲你做這種事情的框架,把它留給框架。
的Error
通常不應該被捕獲,因爲它表示應該永遠不會發生異常情況。
從爲Error
類的Java API規範:
的
Error
是Throwable
表示的嚴重問題 合理應用程序不應該試圖 趕上一個子類。大多數此類錯誤是 異常情況。 [...]不需要在 聲明其throws子句中可能的 執行方法的過程中被拋出,但不是 抓住 錯誤的任何子類的方法,因爲這些錯誤是 不應該 出現的異常情況。
由於規範中提到,一個Error
只在那些 機會是,當Error
發生時,很少有應用程序可以做的,在某些情況下,Java虛擬機本身可能的情況下拋出處於不穩定的狀態(如VirtualMachineError
)
雖然Error
是Throwable
一個子類,這意味着它可以通過一個try-catch
條款被抓住了,但它可能是不是真的需要,因爲應用程序將處於異常在JVM拋出Error
時指定狀態。
在Java Language Specification, 2nd Edition的11.5 The Exception Hierarchy部分中還有關於此主題的簡短部分。
非常非常罕見。
我做了它只爲一個非常非常具體的已知案例。 例如,如果兩個獨立ClassLoader加載相同的DLL,java.lang.UnsatisfiedLinkError可能會拋出。 (我同意我應該將JAR移動到共享類加載器)
但最常見的情況是您需要登錄才能知道用戶發出抱怨時發生了什麼。你需要一條消息或一個彈出窗口給用戶,而不是默默地死去。即使是在C/C++中的程序員,他們也會彈出一個錯誤信息,並告訴人們在退出之前不理解的內容(例如內存失敗)。
如果你足夠瘋狂地創建一個新的單元測試框架,你的測試運行器可能需要捕獲任何測試用例拋出的java.lang.AssertionError。
否則,請參閱其他答案。
一般而言,您應該始終抓住java.lang.Error
並將其寫入日誌或將其顯示給用戶。我在支持中工作,每天都會看到程序員無法分辨程序中發生了什麼。
如果你有一個守護線程,那麼你必須防止它被終止。在其他情況下你的應用程序將正常工作。
您應該只在最高級別捕獲java.lang.Error
。
如果你看看錯誤列表,你會發現大部分都可以被處理。例如,在讀取損壞的zip文件時發生ZipError
。
最常見的錯誤是OutOfMemoryError
和NoClassDefFoundError
,它們在大多數情況下都是運行時問題。
例如:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
可以產生OutOfMemoryError
,但它是一個運行時的問題,沒有任何理由終止你的程序。
NoClassDefFoundError
如果庫不存在或者您使用另一個Java版本,則會發生這種情況。如果它是您的程序的可選部分,那麼您不應該終止您的程序。
我可以給出更多的例子,說明爲什麼在頂層捕獲Throwable
併產生有用的錯誤消息是一個好主意。
在多線程環境中,你最想要抓住它!當你抓住它,記錄它,並終止整個應用程序!如果你不這樣做,那麼可能會做一些關鍵部分的某個線程就會死機,其他應用程序會認爲一切正常。除此之外,許多不需要的情況都可能發生。 一個最小的問題是,如果其他線程由於一個線程不工作而開始拋出一些異常,您將無法輕鬆找到問題的根源。
例如,通常循環應該是:
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
甚至在某些情況下,你會希望以不同的方式處理不同的錯誤,例如,在OutOfMemoryError異常你就可以定期關閉應用程序(甚至可能免費一些記憶,並繼續),在其他一些情況下,你可以做的事情並不多。
理想情況下,我們不應該在我們的Java應用程序中捕獲錯誤,因爲它是一種異常情況。應用程序將處於異常狀態,並可能導致清理或給出一些嚴重錯誤的結果。
在單元測試中發現檢查斷言的錯誤可能是適當的。如果某人禁用斷言或以其他方式刪除您想要知道的斷言
在Android應用程序中,我正在捕獲java.lang.VerifyError。我正在使用的庫不適用於具有舊版本操作系統的設備,並且庫代碼會拋出此類錯誤。當然我能避免錯誤在運行時檢查操作系統的版本,但:
- 最早支持的SDK可能會在未來的特定庫改變
- 在try-catch錯誤塊中更大的一部分回落機制。一些特定的設備,雖然它們應該支持圖書館,但是會引發例外。我捕獲了VerifyError和所有異常以使用回退解決方案。
當JVM沒有像預期的那樣工作或處於邊緣時,出現錯誤。如果你發現一個錯誤,不能保證catch塊會運行,甚至更少的運行直到結束。
它也將取決於正在運行的計算機,當前的內存狀態,所以沒有辦法測試,盡力而爲。你只會有一個糟糕的結果。
您還將降級您的代碼的可讀性。
在測試環境中捕獲java.lang.AssertionError非常方便...
理想情況下,我們不應該處理/捕獲錯誤。但根據框架或應用程序的要求,可能會出現我們需要做的情況。假設我有一個XML解析器守護進程,它實現了DOM解析器,它消耗更多的內存。如果有像Parser這樣的需求線程在得到OutOfMemoryError時不應該死掉,而應該處理它併發送消息/郵件給應用程序/框架的管理員。
- 1. 捕捉java.lang.Error
- 2. 哪個java.lang.Error後裔可以安全捕獲?
- 3. 「Exception in thread」main「java.lang.Error
- 4. 序列化java.lang.Error的
- 5. 何時以及如何捕獲異常
- 6. 是否可以拋出java.lang.Error?
- 7. Unity Android遊戲崩潰 - java.lang.Error
- 8. 關於Java.lang.Error的問題
- 9. 何時明智地捕獲NullPointerException?
- 10. 如何捕獲編譯時異常?
- 11. JMS連接建立時如何捕獲?
- 12. Firebase:如何實時捕獲數據
- 13. WPF - 按下CTRL + SHIFT時如何捕獲?
- 14. 何時在代碼中捕獲RuntimeExceptions?
- 15. 何時在Python中捕獲MemoryError?
- 16. 即時屏幕捕獲Java
- 17. 插入時捕獲RowVersion
- 18. WorldPay實時API「捕獲」
- 19. 在編譯時捕獲ArrayStoreException
- 20. 救援和同時捕獲
- 21. 捕獲時間框架
- 22. JSF捕獲會話超時
- 23. AVCaptureVideoDataOutput實時幀捕獲
- 24. 捕獲響應時間
- 25. 僅捕獲超時異常
- 26. 使用HttpException捕獲超時
- 27. EXC_BAD_ACCESS當捕獲GPU幀時
- 28. Geopy:捕獲超時錯誤
- 29. C++二進制到Java獲取「java.lang.Error:無效的內存訪問」
- 30. 如何捕獲NSWorkspaceDidPerformFileOperationNotification?
另請參閱http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror – Raedwald 2016-04-02 14:41:46