摘要:可以被異常處理機制使用,是異常處理的核心。非檢測異常,在編譯時,不會提示和發現異常的存在,不強制要求程序員處理這樣的異常??傮w來說,語言的異常處理流程,從程序中獲取異常信息。處理運行時異常,采用邏輯合理規避同時輔助處理。
目錄
什么是Java異常?
當一個Exception在程序中發生的時候,JVM是怎么做的呢?
當我們編寫程序的時候如何對待可能出現的異常呢?
正文1. 什么是Java異常?
今天我們來聊聊java異常,異常是導致程序中斷執行的一種指令流。我們在提高代碼穩定性和健壯性的時候,常常會花更多的時間去考慮,代碼可能存在的異常。編碼中對可能的發生的異常先一步正確處理,就可以確保異常不會導致程序不可用。說了這么多異常,那么異常是什么呢?
Java異常是一種導致程序中斷的執行指令流。它存在應用服務器硬件錯誤、程序編寫的時候未考慮數組越界、也可能是網絡通信中網絡抖動的客觀原因導致的異常等情況。異??赡苁侵饔^代碼設計不周全也可能是客觀硬件報錯,那么認識異常就是避免異常的第一步。我們先從異常家族的認識開始,下面異常的族譜:
Throwable類作為所有異常的發源,他是整個Java異常體系的超體,其下面分為Error和Exception兩大類。
Error與其子類實例代表嚴重系統錯誤,應用程序無法處理,如硬件層面的錯誤、JVM錯誤或內存不足等問題,這種錯誤發生時Java應用程序本身無力恢復。Error對象拋出時,基本上不用處理,任其傳播至JVM為止,應用程序能做的最多留下日志信息。
Exception代表程序運行時發送的各種不期望發生的事件。可以被Java異常處理機制使用,是異常處理的核心。Exception及其子類可以被程序處理,也就是所在應用程序中正確的處理了Exception及其子類就能提高代碼的穩定性和健壯性。
Exception類下面分為檢測異常和非檢測異常:
檢測異常,是JVM強制要求程序員為可能出現的異常做預備處理工作。JVM規定檢測異常要么使用try-catch語句捕獲它并進行處理,要么使用throws子句聲明并拋出它,否者javac在編譯程序會不通過。這類異常一般是程序運行環境導致的,為了預防未知環境對程序的影響,規定程序員需要處理這類異常。
非檢測異常,javac在編譯時,不會提示和發現異常的存在,JVM不強制要求程序員處理這樣的異常。當然,作為程序員我們應該預防這樣的異常導致程序崩潰,所以建議使用try-catch-finally處理它。這類異常原因多半是代碼寫的邏輯有問題或考慮不周全。
2.當一個Exception在程序中發生的時候,JVM是怎么做的呢?
對java整體異常家族有了大致的認識之后,那么當一個Exception在程序中發生的時候,JVM是怎么做的呢?
認識這個問題,我們首看看JVM是如何執行java代碼的,JVM將class文件轉換為JVM的java類。JVM為java類建立方法表,方法表中的索引可以引導JVM找到需要執行的方法體和JVM方法執行棧。當然,invokemethod調用執行一個方法的時候,Java虛擬機把描述該方法的棧結構置入方法執行棧棧頂,位于棧頂的方法為正在執行的方法。 JVM會為每一個方法建立執行的堆和棧用于存放執行中的變量,如果此時程序出現一個Exception,拋出的異常先轉移給合適的異常處理語句。代碼的執行會被相應的Exception執行流接管,將方法表信息、發生異常的位置信息和方法的堆棧信息壓入Exception的堆棧,當程序中斷的時候IDE就會將Exception的堆棧信息打印出來。
如果我們通過try…..catch….finally語句來處理異常,處理流程又是怎樣的呢?在try代碼塊中拋出的異常,代碼執行流會跳轉到catch代碼塊執行,catch代碼塊可以對發生的異常進行補救。讓代碼回歸到正常的執行流程。finally語句,無論在try模塊中是否發生異常,都會執行finally語句,使用finally語句主要是為了釋放被占用的資源,比如打開的文件或鏈接的通信資源等。
總體來說,Java語言的異常處理流程,從程序中獲取異常信息。根據Java的源文件和用戶調用的包列表,JVM可以獲取該程序包括Java API所引發的異常在內的異常處理的信息,這些信息包括:異常引發位置、異常拋出順序、引發異常的方法名和類名等。這些異常信息在程序異常的排查和修改的時候非常重要,后面會講到如何正確處理這些異常。
3.當我們編寫程序的時候如何對待可能出現的異常呢?
通常在發生異常的時候我們有兩種處理模型:終止與恢復。
終止模型:前提是假設錯誤非常關鍵,以至于程序無法返回到程序正常運行軌跡,一旦異常拋出就意味著程序將停止提供服務。如:數據庫連接異常發生。
恢復模型:也就是異常程序發生錯誤,錯誤可以被修復然后重新回到正常程序執行的軌跡上。例如,我們可以將數據庫連接try。。。catch置于循環中,一次連接不成功可以循環下一次進行連接。
配合終止和恢復模型,我們會配合使用throw和throws語法。throws關鍵字主要在方法簽名中使用,用于聲明該方法可能拋出的異常。throws 可以理解成是一種通知行為,沒有實際的拋出異常的動作,而僅僅是告訴調用他的上層函數,這里可能會拋出這個異常;
throw用于在函數體內語句中,表示拋出一個實際的異常的實際動作,如果在函數內沒有捕獲并處理,那么將會一直向上拋出這個異常直到被main()/Thread.run()拋出。
我們了解了Java的異常內容之后,在程序中遵循怎樣的行業規則和大牛的經驗合理使用異常,提高代碼的穩定性呢?
下面整理了包括Effective Java異常使用指導原則和網上博客內容:
不要講異常處理用于正常的控制流(設計良好的API不應該強迫它的調用者為了正常的控制流而使用異常)。
對可以恢復的情況使用了受檢異常,對編程錯誤使用運行時異常。
避免不必要的使用受檢異常(可以通過一些狀態檢測手段來避免異常的發生)。
優先使用標準異常。
每個方法拋出的異常都要有文檔。
保持異常的原子性。
不要再catch中忽略掉捕獲到的異常。
處理運行時異常,采用邏輯合理規避同時輔助try…catch處理。
在多重catch快后面,可以加一個catch(Exception)來處理可能會被遺漏的異常。
對于不確定的代碼,也可以加上try…catch,處理潛在的異常。
盡量去處理異常,切忌只是簡單的調用printStackTrace()打印輸出。
具體如何處理異常,要根據不同的業務需求和異常類型去決定。
盡量添加finally語句塊去釋放占用的資源。
不要被這么多規則嚇到了,不需要逐條強記他們。我對異常的理解,首先態度上要謙虛明白代碼中很難避免因為考慮不周出現的異常,所以編碼時應該采用防衛式編碼。其次在編碼處理過程中使用try…catch…finally語句預防可能的異常,采用合適的異常處理模式對待程序可能的異常。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76989.html
摘要:不受檢查異常為編譯器不要求強制處理的異常,檢查異常則是編譯器要求必須處置的異常。潛在的異常處理器是異常發生時依次存留在調用棧中的方法的集合。當運行時系統遍歷調用棧而未找到合適的異常處理器,則運行時系統終止。異常處理涉及到五個關鍵字,分別是。 概念 程序運行時,發生的不被期望的事件,它阻止了程序按照程序員的預期正常執行,這就是異常。 異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并...
摘要:異常也就是指程序運行時發生錯誤,而異常處理就是對這些錯誤進行處理和控制。有兩個重要的子類異常和錯誤,二者都是異常處理的重要子類,各自都包含大量子類。需要注意的是,一旦某個捕獲到匹配的異常類型,將進入異常處理代碼。 1,異?,F象 程序錯誤分為三種:1,編譯錯誤;2,運行時錯誤;3,邏輯錯誤。 編譯錯誤是因為程序沒有遵循語法規則,編譯程序能夠自己發現并且提示我們錯誤的原因和位置,這...
摘要:根據異常對象判斷是否存在異常處理。否則,范圍小的異常會因異常處理完成而無法處理。異常處理中使用作為異常的統一出口。 參考《第一行代碼java》《java程序設計教程》java中程序的錯誤有語法錯誤、語義錯誤。如果是語法性錯誤,在編譯時就可以檢查出來并解決。語義錯誤是在程序運行時出現的,在編譯時沒有錯誤,但在運行時可能會出現錯誤導致程序退出,這些錯誤稱為異常。在沒有異常處理的情況下,也即...
摘要:為可恢復的錯誤使用檢查型異常,為編程錯誤使用非檢查型錯誤。檢查型異常保證你對錯誤條件提供異常處理代碼,這是一種從語言到強制你編寫健壯的代碼的一種方式,但同時會引入大量雜亂的代碼并導致其不可讀。在編程中選擇檢查型異常還是運行時異常。 異常處理是Java 開發中的一個重要部分。它是關乎每個應用的一個非功能性需求,是為了處理任何錯誤狀況,比如資源不可訪問,非法輸入,空輸入等等。Java提供了...
閱讀 821·2019-08-30 14:05
閱讀 1712·2019-08-30 11:08
閱讀 3216·2019-08-29 15:41
閱讀 3591·2019-08-23 18:31
閱讀 1510·2019-08-23 18:29
閱讀 546·2019-08-23 14:51
閱讀 2103·2019-08-23 13:53
閱讀 2126·2019-08-23 13:02