当前位置: 首页 > article >正文

Java中的try-catch在jvm层面是怎么做的?

简单描述

java中的try-catch通过异常表栈展开来实现

异常表(exception-table)

每个方法的字节码中都有一个异常表,用于记录try-catch块的作用范围对应的异常处理逻辑

异常表的每个条目包含以下信息:

起点,终点,处理代码的位置,捕获异常的类型

起点(start_pc):try块的起始指令偏移量

终点(end_pc):try块的结束指令偏移量(不包含该指令)

处理代码位置(handler_pc):catch块的第一条指令偏移量

捕获的异常类型(catch_type):要捕获的异常类(如java/lang/Exception),若为0表示捕获所有异常(finally块)

字节码结构

Exception table:start  end  handler  type0      10   13       java/io/IOException0      10   20       java/lang/Exception

异常处理流程

抛出异常,从异常表判断异常是否在处理逻辑内(也就是是否被try-catch{}包围),

代码中抛出异常时,JVM会执行以下步骤:

创建异常对象:实例化抛出的异常(如new IOException()

查找异常表:从当前方法的异常表中,按顺序匹配以下条件:

异常抛出的位置是否在某个条目的[start_pc, end_pc)范围内。

抛出的异常是否是catch_type的子类(或自身)

跳转到处理代码

若找到匹配条目,跳转到handler_pc执行catch

若未找到,触发栈展开:弹出当前栈帧,回到调用者方法重复上述过程。栈展开确保异常沿调用链向上传播,直到被处理或终止线程

未捕获异常:若所有栈帧均未处理异常,线程终止并打印堆栈跟踪


finally块的实现

finally 块的核心是:无论 try 或 catch 块中是否抛出异常或提前返回,finally 中的代码必须执行

为了实现这一点,JVM 的编译器(如 javac)在生成字节码时,会通过两种机制来确保 finally 的执行

finally块通过两种方式实现:

代码复制:编译器将finally代码复制到trycatch块的所有退出路径(包括return或异常抛出之后)。

异常表条目兜底:若finally需要处理异常退出,会生成一个catch_type=0的条目,捕获所有异常并执行finally代码,之后重新抛出异常


代码复制

编译器会将 finally 块中的代码复制到所有可能的退出路径,包括:

try 块正常结束后的退出路径。

catch 块处理完异常后的退出路径。

try 或 catch 块中的 return、break、continue 语句之前

java代码

public void example() {try {System.out.println("try");} catch (Exception e) {System.out.println("catch");} finally {System.out.println("finally");}
}

编译后的字节码逻辑

// try 块
L0:System.out.println("try");// 复制 finally 代码到 try 块末尾System.out.println("finally");return;// catch 块
L1:System.out.println("catch");// 复制 finally 代码到 catch 块末尾System.out.println("finally");return;// 异常表条目(自动处理异常后的 finally)
Exception table:start=L0, end=L0, handler=L1, type=Exception

关键点:

finally 的代码会被复制到 try 和 catch 的末尾,确保正常流程下一定会执行

如果 try 或 catch 中有 return,编译器会先执行 finally 代码,再执行 return


异常表兜底(处理未捕获的异常)

如果 try 或 catch 块中抛出了未被捕获的异常,或者有 throw 语句,JVM 会通过异常表跳转到 finally 代码,执行后再重新抛出异常。

异常表条目

编译器会生成一个特殊的异常表条目用于捕获所有类型的异常(catch_type=0)

确保任何未处理的异常都会先执行 finally,再继续传播异常

java代码

public void example() {try {throw new IOException();} finally {System.out.println("finally");}
}

字节码的异常表会生成如下头目

Exception table:start=L0, end=L1, handler=L2, type=0  // type=0 表示捕获所有异常

对应的执行流程:

  1. try 块抛出 IOException
  2. JVM 查找异常表,发现 type=0 的条目(匹配所有异常)。
  3. 跳转到 handler=L2finally 代码的位置)执行 System.out.println("finally")
  4. 重新抛出异常,继续栈展开

假设代码中有 try 和 finally,但没有 catch:

try {throw new Exception();
} finally {System.out.println("finally");
}

执行步骤:

  1. try 块抛出异常,JVM 创建异常对象。
  2. 直接查找当前方法的异常表,找到 catch_type=0 的条目,跳转到 finally 代码。
  3. 执行 finally 块中的代码。
  4. 重新抛出异常,由外层调用者处理

相关文章:

Java中的try-catch在jvm层面是怎么做的?

简单描述 java中的try-catch通过异常表和栈展开来实现 异常表(exception-table) 每个方法的字节码中都有一个异常表,用于记录try-catch块的作用范围和对应的异常处理逻辑 异常表的每个条目包含以下信息: 起点,终点…...

c# txt文档的实时显示,用来查看发送接收指令

通讯历史按钮 private void uiButton1_Click(object sender, EventArgs e){try{logf new logF();logf.Show();}catch (Exception){throw;} }主页面关闭函数(点击保存就为true true就不删除) private void page1_FormClosed(object sender, FormClos…...

Excel 数据转换为SQL语句

文章目录 一、制作公式二、示例图 一、制作公式 1、找一列空白的,选中一个单元格,输入"",在双引号中写入INSERT语句脚本,然后回车。 // 数字代表行数 “INSERT INTO PayList (product, rmb) VALUES (”&A10&“…...

FFmpeg处理流程

结构体 AVFormatContext 作用:管理媒体文件的封装格式上下文,存储文件格式、流信息、I/O 操作等元数据。 关键字段 AVInputFormat *iformat; // 输入格式(如MP4、FLV) AVStream **streams; // 音视频流数组 int nb_str…...

SpringMVC (一)基础

目录 SpringMVC 一 简单使用 1 新建模块选择指定参数 2 创建实现类 3 将项目启动 4 运行结果:在浏览器当中响应执行 二 RequestMapping 三 请求限定 SpringMVC SpringMVC是Spring的web模块,用来开发Web应用,SpringMVC应用最终作为B/…...

通过deepseek学习lua写网页

提问1:html通过post调用lua代码 要通过HTML页面调用Lua代码,通常需要一个服务器端环境来处理HTTP请求并执行Lua代码。HTML本身无法直接执行Lua代码,因为Lua是一种服务器端脚本语言,而HTML是客户端标记语言。 以下是一个简单的示…...

windows第十二章 MFC控件常用消息

文章目录 控件反射消息机制文本框控件EN_CHANGE消息EN_UPDATE消息EN_SETFOCUS消息EN_KILLFOCUS消息EN_MAXTEXT消息EN_ERRSPACE消息EN_HSCROLL消息 按钮控件BN_CLICKED消息BN_DOUBLECLICKED消息BN_SETFOCUS消息BN_KILLFOCUS消息 单选按钮BN_CLICKED 消息 复选框BN_CLICKEDBN_DOU…...

基于C语言的简单HTTP Web服务器实现

1. 概述 本案例使用C语言实现了一个简单的HTTP服务器,能够处理客户端的GET请求,并返回静态文件(如HTML、图片等)。在此案例中案例,我们主要使用的知识点有: Socket编程:基于TCP协议的Socket通信…...

JavaScript语言的区块链隐私

使用JavaScript保护区块链隐私 随着区块链技术的快速发展,隐私保护的重要性日益凸显。区块链技术虽然在透明性和去中心化方面表现优异,但其公开账本特性也使得用户的交易和身份信息容易暴露。因此,如何在区块链应用中实现隐私保护成为了一个…...

ZYNQ初识13(zynq_7020)hdmi和串口板载功能的验证

(1)另:首先需要确认供电模块,电压转换模块没有问题,测量后上电防止出现短路。通过vivado下载bit流文件检测JTAG下载口是否正常,如可正常检测,才可进行下一步验证。 (2)以…...

ollama下载的DeepSeek的模型(Model)文件在哪里?(C盘下)

目录 一、下载大模型(DeepSeek) 2. 安装 Ollama 3. 检查安装是否成功 二、拉取大模型(DeepSeek) 1. 打开命令行 2. 下载模型 3. 测试下载 4. 等待下载完成 三.模型存放路径 这个位置!! 在人工智能…...

docker的anythingllm和open-webui压缩包分享(国内镜像拉取,百度云压缩包分享)

文章目录 前言第一部分:镜像获取🚀 方式一:切换国内下载镜像✅1. 下载anythingllm✅ 2. 下载open-webui 🚀方式二:下载我分享的百度云✅ anythingllm压缩包百度云链接❎ open-webui压缩包 第二部分:下载之后…...

树莓科技(成都)集团:如何铸就第五代产业园标杆

树莓科技(成都)集团铸就第五代产业园标杆,主要体现在以下几个方面: 精准定位与前瞻布局 树莓科技并非盲目扩张,而是精准锚定数字经济发展方向。以成都为起点,迅速构建起全国性的园区版图,体现…...

父组件中循环生成多个子组件时,有且只有最后一个子组件的watch对象生效问题及解决办法

提示:父组件中循环生成多个子组件时,有且只有最后一个子组件的watch对象生效问题及解决办法 文章目录 [TOC](文章目录) 前言一、问题二、解决方法——使用function函数代替箭头函数()>{}总结 前言 ‌‌‌‌‌问题:子组件用that解决watch无…...

《解锁Flutter:跨平台开发的未来之光》

《解锁Flutter:跨平台开发的未来之光》 Flutter:崭新时代的跨平台框架 在当今数字化浪潮中,移动应用已成为人们生活中不可或缺的一部分。无论是购物、社交、娱乐还是办公,我们都离不开各种手机应用。而在移动应用开发领域&#…...

求递增子序列LIS的两种方法

文章目录 前言一、普通动态规划(DP)求解LIS1.DP思路2.DP的状态定义与转移方程3.DP的时间与空间复杂度4.DP代码实现5.DP的图文示例 二、贪心 二分查找求解LIS1.思路分析2.贪心 二分的时间与空间复杂度 三. 模板题讲解1.洛谷B3637 最长上升子序列1.dp写法…...

【Linux篇】进程状态(僵尸进程,孤儿进程),优先级与调度机制

📌 个人主页: 孙同学_ 🔧 文章专栏:Liunx 💡 关注我,分享经验,助你少走弯路! 文章目录 1. 前文铺垫理解内核链表 2. 进程状态2.1 进程状态查看2.2 僵尸进程2.3 僵尸进程危害2.4 孤儿…...

SAP-ABAP:CONV(显示类型转换符)关键字详解

SAP ABAP CONV 关键字详解 CONV 是 ABAP 7.40 版本引入的显式类型转换操作符,用于将表达式的结果强制转换为指定的数据类型。它提供了一种清晰且类型安全的方式处理数据转换,避免隐式转换的潜在风险。以下是其核心特性和应用场景的全面解析:…...

AI应用加速落地丨MaxKB正在被政府、公共事业、教育和医疗行业用户广泛采纳

2025年2月至3月上旬,伴随着各个行业接入并使用DeepSeek,MaxKB开源知识库问答系统正在被越来越多的行业用户所采纳,是人工智能行业落地的强应用。目前,MaxKB在政府、公共事业、教育和医疗四大行业已经拥有了众多典型案例&#xff0…...

⚡️Jolt -- 通过JSON配置来处理复杂数据转换的工具

简介:一个能够通过JSON配置(特定的语法)来处理复杂数据转换的工具。 比如将API响应转换为内部系统所需的格式,或者处理来自不同来源的数据结构差异。例如,将嵌套的JSON结构扁平化,或者重命名字段&#xff0…...

Django系列教程(7)——路由配置URLConf

目录 URLconf是如何工作的? path和re_path方法 更多URL配置示例 URL的命名及reverse()方法 使用命名URL 硬编码URL - 不建议 URL指向基于类的视图(View) 通过URL传递额外的参数 小结 Django的项目文件夹和每个应用(app)目录下都有urls.py文件,它们构成了D…...

TDengine SQL 函数

单行函数 数学函数 ABSACOSASINATANCEILCOSDEGREESEXPFLOORGREATESTLEASTLNLOGMODPIPOWRADIANSRANDROUNDSIGNSINSQRTTANTRUNCATE 字符串函数 ASCIICHARCHAR_LENGTHCONCATCONCAT_WSLENGTHLOWERLTRIMPOSITIONREPEATREPLACERTRIMSUBSTRING/SUBSTRSUBSTRING_INDEXTRIMUPPER 转换函数…...

二维数组基础

在 C 语言中,二维数组是一种数据结构,它可以存储表格形式的数据,或是矩阵形式的数据。二维数组可以被看作是一个包含多个一维数组的数组,因此它有两个维度:行和列。 1. 二维数组的定义与声明 在 C 语言中,二维数组的定义形式如下: data_type array_name[rows][column…...

2024年第十五届蓝桥杯软件C/C++大学A组——五子棋对弈

蓝桥杯原题: 题目描述: “在五子棋的对弈中,友谊的小船说翻就翻? ” 不!对小蓝和小桥来说,五子棋不仅是棋盘上的较量,更是心与心之间的沟通。这两位挚友秉承着 “ 友谊第一,比赛第二…...

复试难度解析,西电先进材料与纳米科技学院学院考研录取情况

01、先进材料与纳米科技学院各个方向 02、24先进材料与纳米科技学院近三年复试分数线对比 PS:材料院24年院线学硕方向降低10分,专硕上涨15分;材料院在分数线相对于其他211、985院校对比来看,依然分数偏低,推荐大家关注…...

Deepseek Chatgpt Kimi 推荐的深度学习书单

朋友让推荐一些深度学习的书,让 Deepseek、Chatgpt、Kimi 分别生成了一份书单并做了对比,记录一下以备以后用到。 Chatgpt 推荐的深度学习书 1. chatgpt 推荐的书目截图 1.2 Chatgpt 推荐的深度学习书目文字版 如果你想学习 Deep Learning&#xff0…...

高频面试题(含笔试高频算法整理)基本总结回顾25

干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言&#xff0c…...

ClickHouse SQL优化:解锁高性能数据分析的关键

一、引言 1.1 ClickHouse的背景与优势 ClickHouse是一款高性能的列式数据库,专为在线分析处理(OLAP)场景设计。它以其卓越的读写性能、强大的数据压缩能力和灵活的SQL支持而闻名。ClickHouse能够轻松处理PB级数据,并在亚秒级内返回查询结果,这使其成为大数据分析领域的理…...

我与DeepSeek读《大型网站技术架构》(14)- 架构师领导艺术

文章目录 架构师领导艺术以人为本:激发团队潜能开放式协作:打破架构“所有权”壁垒妥协的艺术:聚焦核心目标成就他人:构建持续进化团队高效沟通:建立技术与人性的平衡 架构师领导艺术 本章聚焦架构师如何通过团队协作…...

mac安装mysql之后报错zsh: command not found: mysql !

在Mac上安装MySQL后,如果终端中找不到mysql命令,通常是 因为MySQL的命令行工具(如mysql客户端)没有被正确地添加到你的环境变量中。 检查 MySQL 是否已安装 ps -ef|grep mysql查看到路径在 /usr/local/mysql/bin 查看 .bash_pro…...