【异常】浅析异常体系及为什么一定会执行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.mzph.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…