【異常】淺析異常體系及為什么一定會執行finally塊代碼

異常體系:

? ? ? ? (1)所有異常(Exception)、錯誤(Error)都繼承自異常中的基類:Throwable。而異常又可以分為檢查異常(Checked Exception)、非檢查異常(Unchecked Exception)兩大類。

? ? ? ? (2)檢查異常在編譯期間由編譯器檢查的異常,編譯器確保這些異常在編譯期被處理,意味著不能直接使用關鍵字throw拋出異常,要么使用try、catch處理異常,要么在方法聲明上使用throws關鍵字提醒方法調用者該方法可能會拋出的異常,讓方法調用者處理異常。Exception從屬子類中,除了RuntimeException類及其從屬子類,其它子類都屬于這一類型的異常。

? ? ? ? 直接拋出檢查異常:

? ? ? ? 編譯器直接報錯,提示該異常需要處理。

? ? ? ? 使用try、catch捕獲異常:

? ? ? ? 編譯器不會報錯,因為在catch塊捕獲了異常,并進行了處理(e.printStackTrace())。

? ? ? ? 在方法簽名上拋出異常:

? ? ? ? 編譯器不會報錯,因為在調用該方法時,編譯器會強制要求方法調用者使用try、catch捕獲異常進行處理,或者繼續通過throws關鍵字往上拋,讓更上一層的方法調用者進行處理。

? ? ? ? (3)非檢查異常編譯器不會在編譯期間就檢查這類異常,直接拋出這類異常編譯器不會報錯,只有在程序運行時才可能拋出的異常。RuntimeException及其從屬子類、Error及其從屬子類都屬于這類異常。

? ? ? ? 直接拋出非檢查異常:

? ? ? ? 編譯器不會報錯,因為非檢查異常只會在程序運行時才會進行相應處理。

? ? ? ? (4)如果想自定義檢查異常,那么讓類直接繼承Exception類即可;如果想自定義非檢查異常,那么讓類直接繼承自RuntimeException即可。

? ? ? ? 自定義檢查異常

? ? ? ? 自定義非檢查異常

異常處理機制:

? ? ? ? (1)try-catch字節碼解析

? ? ? ?JavaCodes

public class TestMyException{public static void main(String[] args) {System.out.println("使用try、catch捕獲自定義檢查異常");try {throw new MyException();} catch (MyException e) {//將自定義檢查異常封裝成非檢查異常throw new RuntimeException(e);}}
}
class MyException extends Exception{}

? ? ? ? ByteCodes

    Code:stack=3, locals=2, args_size=10: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #3                  // String 使用try、catch處理檢查異常5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: new           #5                  // class com/hammajang/springbootdemo/entity/MyException11: dup                               //s 復制異常對象引用12: invokespecial #6                  // Method com/hammajang/springbootdemo/entity/MyException."<init>":()V15: athrow                            // 拋出MyException異常16: astore_1                          // 將捕獲的異常對象存儲在局部變量表中17: new           #7                  // class java/lang/RuntimeException20: dup                               // 復制異常對象引用21: aload_1                           // 將局部變量中的異常對象加載到操作數棧22: invokespecial #8                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V25: athrow                            // 拋出RuntimeException異常Exception table:from    to  target type8    16    16   Class com/hammajang/springbootdemo/entity/MyException

? ? ? ? Exception table含義如果執行指令8-指令16(try塊)的過程中拋出了MyException類型的異常,則跳轉到指令16(finally塊)繼續執行。

? ? ? ? (2)try-catch-finally字節碼解析

? ? ? ? JavaCodes

public class TestMyException{public static void main(String[] args) {System.out.println("使用try、catch捕獲自定義檢查異常");try {throw new MyException();} catch (MyException e) {//將自定義檢查異常封裝成非檢查異常throw new RuntimeException(e);} finally {System.out.println("TestMyException finally code...");}}
}

? ? ? ? ByteCodes

    Code:stack=3, locals=3, args_size=10: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #3                  // String 使用try、catch捕獲自定義檢查異常5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: new           #5                  // class com/hammajang/springbootdemo/entity/MyException11: dup                               // 復制異常對象引用12: invokespecial #6                  // Method com/hammajang/springbootdemo/entity/MyException."<init>":()V15: athrow                            // 拋出異常16: astore_1                          // 將異常對象存儲在局部變量表中17: new           #7                  // class java/lang/RuntimeException20: dup                               // 復制異常對象引用21: aload_1                           // 將局部變量表中的異常對象加載到操作數棧22: invokespecial #8                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V25: athrow                            // 拋出異常26: astore_2                          // 將異常對象存儲在局部變量表中27: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;30: ldc           #9                  // String TestMyException finally code...32: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V35: aload_2                            36: athrowException table:from    to  target type8    16    16   Class com/hammajang/springbootdemo/entity/MyException8    27    26   any

????????Exception table加了finally塊后,異常表中多了一條記錄,表示從指令8-指令27(try塊、catch塊)如果拋出了任意類型(any)的異常,都會跳轉到指令26(finally塊)繼續執行。

finally塊解析:

? ? ? ? (1)模擬空指針異常

? ? ? ? JavaCodes

public class TestMyException{public static void main(String[] args) {MyException exception = null;try{exception.test();}catch (Exception e){System.out.println(e);}finally {exception = new MyException();}}
}
class MyException extends Exception{public void test(){System.out.println("test method");}
}

? ? ? ? ByteCodes

    Code:stack=2, locals=4, args_size=10: aconst_null1: astore_12: aload_13: invokevirtual #2                  // Method com/hammajang/springbootdemo/entity/MyException.test:()V6: new           #3                  // class com/hammajang/springbootdemo/entity/MyException9: dup10: invokespecial #4                  // Method com/hammajang/springbootdemo/entity/MyException."<init>":()V13: astore_114: goto          4717: astore_218: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;21: aload_222: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V25: new           #3                  // class com/hammajang/springbootdemo/entity/MyException28: dup29: invokespecial #4                  // Method com/hammajang/springbootdemo/entity/MyException."<init>":()V32: astore_133: goto          4736: astore_337: new           #3                  // class com/hammajang/springbootdemo/entity/MyException40: dup41: invokespecial #4                  // Method com/hammajang/springbootdemo/entity/MyException."<init>":()V44: astore_145: aload_346: athrow47: returnException table:from    to  target type2     6    17   Class java/lang/Exception2     6    36   any17    25    36   any

有三處地方的指令需要我們注意

? ? ? ? 1、指令6、指令9、指令10(try

? ? ? ? 2、指令25、指令28、指令29(catch

? ? ? ? 3、指令37、指令40、指令41(finally

? ? ? ? 這三處地方的指令都執行同一個操作:創建并初始化MyException對象

????????從字節碼層面我們就可以得知為什么finally塊的代碼一定會執行了,因為在將.java文件編譯成.class字節碼文件時,編譯器會將finally塊的代碼放在try塊、catch塊的末尾

? ? ? ? 在Exception table中我們也可以看到,在指令2-指令6(try塊)、指令17-25(catch塊)執行時,如果拋出了任意(any)類型的異常,就會跳轉到指令36(finally塊)繼續執行。

? ? ? ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209551.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209551.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209551.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

msvcp100.dll丟失的常見原因/msvcp100.dll丟失的解決方法分享

在計算機使用過程中&#xff0c;我們經常會遇到一些錯誤提示&#xff0c;其中之一就是“msvcp100.dll丟失”。這個錯誤提示通常出現在運行某些程序或游戲時&#xff0c;給使用者帶來了很大的困擾。那么&#xff0c;究竟是什么原因導致了msvcp100.dll文件的丟失呢&#xff1f;本…

ubuntu22.04在opencv4的基礎上安裝opencv3

安裝opencv4 首先在ubuntu22.04上安裝opencv4&#xff0c;可以參考之前的博客ubuntu22.04安裝opencv4和opencv_contrib-CSDN博客 安裝opencv3 由于有使用opencv3的需求&#xff0c;所以需要繼續安裝opencv3 ; 安裝編譯 這里安裝的版本是opencv3.4.5&#xff0c;大致安裝思…

STM32F1之CAN介紹

目錄 ?編輯 1. CAN 是什么&#xff1f; 2. 總線拓撲圖 3. CAN 的特點 4. CAN 協議的基本概念 1. CAN 是什么&#xff1f; CAN 是 Controller Area Network 的縮寫&#xff08;以下稱為 CAN&#xff09;&#xff0c;是 ISO*1 國際標準化的串行通信協議。 在當前的汽車產…

javaWebssh學生系統myeclipse開發mysql數據庫MVC模式java編程計算機網頁設計

一、源碼特點 java ssh學生管理系統是一套完善的web設計系統&#xff08;系統采用ssh框架進行設計開發&#xff09;&#xff0c;對理解JSP java編程開發語言有幫助&#xff0c;系統具有完整的源代碼和數據庫&#xff0c;系統主要采用B/S模 式開發。開發環境為TOMCAT7.0,My…

前端開發中,Web Storage的存儲數據的方法localstorage和sessionStorage的使用及區別

在 Web瀏覽器中存儲數據以改善用戶體驗和提升Web應用程序性能是非常常見的。在大多數情況下&#xff0c;可供我們使用就是LocalStorage和SessionStorage。 本文中&#xff0c;我們將會從安全性和用戶體驗兩個方面對SessionStorage和LocalStorage進行評估。然后我們將討論如何根…

Linux驅動安裝遇到的問題(Kernel configuration is invalid)(Invalid module format)

Linux驅動編譯安裝遇到的問題&#xff08;Kernel configuration is invalid&#xff09;&#xff08;Invalid module format&#xff09; 前言1. Kernel configuration is invalid2. Invalid module format2.1 第一種情況&#xff1a;內核模塊編譯的環境與現在insmod想要運行的…

python:mplfinance 畫K線圖+布林線

pip install mplfinance ; python 安裝使用 TA-lib 安裝主要在 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 這個網站找到 TA_Lib-0.4.24-cp310-cp310-win_amd64.whl pip install /pypi/TA_Lib-0.4.24-cp310-cp310-win_amd64.whl 編寫 mpf_kline_boll.py 如下 # -*- cod…

英語口語練習(背誦老友記)

There is nothing to tell! 這沒什么好說的&#xff01; Hes just some guy I work with. 他不過是我的同事。 Cmon, youre going out with the guy! 少來了&#xff0c;你們都在約會了&#xff01; Theres gotta be something wrong with him! 這個男人一定有什么問題&…

華為OD機試真題-快遞員的煩惱-2023年OD統一考試(C卷)

題目描述: 快遞公司每日早晨,給每位快遞員推送需要送到客戶手中的快遞以及路線信息,快遞員自己又查找了一些客戶與客戶之間的路線距離信息,請你依據這些信息,給快遞員設計一條最短路徑,告訴他最短路徑的距離。 注意: 1. 不限制快遞包裹送到客戶手中的順序,但必須保證都…

【VRTK】【VR開發】【Unity】12-占位身體

課程配套學習資源下載 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概要】 目前你會發現,就算存在非Trigger Collider的墻壁屏障等,也能夠正常穿過,這會導致不沉浸的體驗。你需要一個占位身體來實現讓墻壁等碰撞并擋住自己…

基于java的貪吃蛇小游戲

貪吃蛇游戲需要做兩點&#xff1a;圖形界面和游戲邏輯。在 Java 中&#xff0c;可以使用 Swing 或 JavaFX 來創建圖形界面。下面代碼創建了一個簡單的 Swing 窗口&#xff0c;實現了一個基本的貪吃蛇游戲。在游戲中&#xff0c;使用方向鍵控制貪吃蛇的移動&#xff0c;吃到食物…

`Numpy`數組中 數據的修改(第10講)

Numpy數組中 數據的修改(第10講) ??????? ??博主 侯小啾 感謝您的支持與信賴。?? ????????????????????????????????????????????????????????????????????????????????????…

YOLOv5獨家原創改進:SPPF自研創新 | 可變形大核注意力(D-LKA Attention),大卷積核提升不同特征感受野的注意力機制

??????本文自研創新改進: 可變形大核注意力(D-LKA Attention)高效結合SPPF進行二次創新,大卷積核提升不同特征感受野的注意力機制。 收錄 YOLOv5原創自研 https://blog.csdn.net/m0_63774211/category_12511931.html ??????全網獨家首發創新(原創),適合p…

Python學習路線 - Python語言基礎入門 - 函數使用

Python學習路線 - Python語言基礎入門 - 函數使用 函數介紹函數函數的快速體驗 函數的定義函數的定義 函數的參數函數的傳入參數函數的傳入參數 - 傳參定義函數的傳入參數 - 語法解析練習案例&#xff1a;升級版自動查詢核酸 函數的返回值函數返回值的定義返回值的語法None類型…

Python----異常

1、什么是異常 當檢測到一個錯誤時&#xff0c;解釋器就無法繼續執行了&#xff0c;反而出現了一些錯誤的提示&#xff0c;這就是所謂的"異常"。 2、異常演示 # 運算符 # print(10/0) # 文件異常 f open(python.txt, r) content f.readlines() print(content) 3…

vue中el-upload結合vuedraggable實現圖片的上傳、排序、刪除以及預覽等功能

實現效果&#xff1a; 功能實現&#xff1a; 要實現圖片的拖拽功能首先需要安裝vuedraggable庫 npm install vuedraggable --save在組件中引入并注冊 vuedraggable <script>import draggable from "vuedraggable";export default {// 注冊組件components: {…

SI24R03 高度集成低功耗SOC 2.4G 收發一體芯片

今天給大家介紹一款Soc 2.4G 收發一體模塊-SI24R03 Si24R03是一款高度集成的低功耗無線SOC芯片&#xff0c;芯片為QFN32 5x5mm封裝&#xff0c;集成了資源豐富的MCU內核與2.4G收發器模塊&#xff0c;最低功耗可達1.6uA&#xff0c;極少外圍器件&#xff0c;大幅降低系統應用成本…

詳解Android單元測試最佳實踐

目的 充分的單元測試就是提高代碼質量最有效的手段之一&#xff0c;而單元測試嚴重依賴代碼的可測試性&#xff0c;本文主要通過一個簡單的DEMO演示如何對Android原生應用進行單元測試&#xff0c;同時示例代碼采用MVP模式以提高代碼的可讀性和可測試性 簡介 在Android原生應…

mmdetection測試保存到新的文件夾,無需標簽

這個是用demo這個代碼測試的&#xff0c;需要先訓練一個pth文件夾&#xff0c;訓練之后再調用pth文件夾進行測試。測試的代碼文件名是&#xff1a;image_demo_new.py&#xff0c;代碼如系所示&#xff1a; # Copyright (c) OpenMMLab. All rights reserved. import asyncio fr…

使用selenium的edge瀏覽器登錄某為

互聯網上基本都是某哥的用法&#xff0c;其實edge和某哥的用法是一樣的就有一下參數不一樣。 一、運行環境 Python&#xff1a;3.7 Selenium&#xff1a;4.11.2 Edge&#xff1a;版本 120.0.2210.61 (正式版本) (64 位) 二、執行代碼 from time import sleepfrom selenium…