摘要:組成指針,指針代表捕獲異常的范圍,就是的范圍。當觸發異常的字節碼的索引值在某個異常表條目的監控范圍內,虛擬機會判斷所拋出的異常和該條目想要捕獲的異常是否匹配。
Java異常知識 1.異常的兩大關鍵因素
(1)拋出異常
1.顯式:應用程序手動拋出異常。具體就是使用throw拋出異常
2.隱式:Java虛擬機對于無法執行的代碼,自動拋出異常
(2)捕獲異常
1.try 代碼塊:用來標記需要進行異常監控的代碼。
2.catch 代碼塊:跟在 try 代碼塊之后,用來捕獲在 try 代碼塊中觸發的某種指定類型的異常。除了聲明所捕獲異常的類型之外,catch 代碼塊還定義了針對該異常類型的異常處理器。在 Java中,try 代碼塊后面可以跟著多個 catch 代碼塊,來捕獲不同類型的異常。Java 虛擬機會從上至下匹配異常處理器。因此,前面的 catch 代碼塊所捕獲的異常類型不能覆蓋后邊的,否則編譯器會報錯。
3.fnally 代碼塊:跟在 try 代碼塊和 catch 代碼塊之后,用來聲明一段必定運行的代碼。它的設計初衷是為了避免跳過某些關鍵的清理代碼,例如關閉已打開的系統資源。在程序正常執行的情況下,這段代碼會在 try 代碼塊之后運行。否則,也就是 try 代碼塊觸發異常的情況下,如果該異常沒有被捕獲,fnally 代碼塊會直接運行,并且在運行之后重新拋出該異常。如果該異常被 catch 代碼塊捕獲,fnally 代碼塊則在 catch 代碼塊之后運行。在某些不幸的情況下,catch 代碼塊也觸發了異常,那么 fnally 代碼塊同樣會運行,并會拋出 catch 代碼塊觸發的異常。在某些極端不幸的情況下,fnally 代碼塊也觸發了異常,那么只好中斷當前 fnally 代碼塊的執行,并往外拋異常。
1.所有異常的父類都是Throwable 2.Error異常是程序的執行狀態無法恢復的狀態,只能中止線程甚至中止JVM的異常 3.Exception是相對Error沒有這么嚴重的異常 4.Runtime Exception和Error都屬于不需要檢查的異常 5.除了Runtime Exception和Error的異常都是Check Exception異常 6.Check Exception異常都是需要顯式捕獲的異常3.Java虛擬機是如何捕獲異常的?
java虛擬機構造異常實例非常昂貴。虛擬機需要生成該異常的棧軌跡。該操作會逐一訪問當前線程的 Java 棧幀,并且記錄下各種調試信息,包括棧幀所指向方法的名字,方法所在的類名、文件名,以及在代碼中的第幾行觸發該異常。
既然異常實例的構造十分昂貴,我們是否可以緩存異常實例,在需要用到的時候直接拋出呢?從語法角度上來看,這是允許的。然而,該異常對應的棧軌跡并非 throw 語句的位置,而是新建異常的位置。
因此,這種做法可能會誤導開發人員,使其定位到錯誤的位置。這也是為什么在實踐中,我們往往選擇拋出新建異常實例的原因。
異常處理器
1.來源:每個方法在編譯的時候都會生成一個異常表。異常表里面的每一個條目都代表一個異常處理器。
2.組成:
(1)from指針,to指針:代表捕獲異常的范圍,就是Try的范圍。
(2)target指針:代表處理器的開始位置,就是catch的起始位置。
(3)捕獲的異常類型。
3.捕獲異常
(1)當程序觸發異常時,Java 虛擬機會從上至下遍歷異常表中的所有條目。當觸發異常的字節碼的索引值在某個異常表條目的監控范圍內,Java 虛擬機會判斷所拋出的異常和該條目想要捕獲的異常是否匹配。如果匹配,Java 虛擬機會將控制流轉移至該條目 target 指針指向的字節碼。
(2)如果遍歷完所有異常表條目,Java 虛擬機仍未匹配到異常處理器,那么它會彈出當前方法對應的Java 棧幀,并且在調用者(caller)中重復上述操作。在最壞情況下,Java 虛擬機需要遍歷當前線程 Java 棧上所有方法的異常表。
4.finally代碼的編譯:當前版本 Java 編譯器的做法,是復制 fnally 代碼塊的內容,分別放在 try-catch 代碼塊所有正常執行路徑以及異常執行路徑的出口中。
代碼1: Try{ Try block } catch { Catch block } finally { Finally block }
代碼2: Try { Try block Finally block } catch { Catch block Finally block } finally{ Finally block }
代碼1是我們的Java代碼,代碼2是編譯之后的Java代碼。5.Java7的 Supressed 異常以及語法糖注意:如果 catch 代碼塊捕獲了異常,并且觸發了另一個異常,那么 fnally 捕獲并且重拋的異常是哪個呢?答案是后者。也就是說原本的異常便會被忽略掉,這對于代碼調試來說十分不利。
針對上節說的會將catch的異常忽略掉,Java7引入了 Supressed 異常處理這個問題。但是使用起來還是很麻煩(沒有感受,
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73759.html
摘要:程序塊若有異常發生,程序的運行便重點,并拋出異常類所產生的對象。關鍵字我們可以使用關鍵字把可能拋出的異常顯式的標注在方法定義的位置從而提醒調用者要注意捕獲這些異常。 ...
摘要:是那些可能在虛擬機正常運行期間拋出的異常的超類。運行時異常定義及其子類都被稱為運行時異常。對于語言中的關鍵字和,虛擬機中并沒有特殊的字節碼指令去支持它們,都是通過編譯器生成字節碼片段以及不同的異常處理器來實現。 前言 在一些傳統的編程語言,如C語言中,并沒有專門處理異常的機制,程序員通常用方法的特定返回值來表示異常情況,并且程序的正常流程和異常流程都采用同樣的流程控制語句。Java語言...
閱讀 2169·2023-04-25 15:00
閱讀 2343·2021-11-18 13:14
閱讀 1154·2021-11-15 11:37
閱讀 3083·2021-09-24 13:55
閱讀 1221·2019-08-30 15:52
閱讀 2644·2019-08-29 12:35
閱讀 3359·2019-08-29 11:04
閱讀 1209·2019-08-26 12:13