【Java从入门到放弃 之 从字节码的角度异常处理】
从字节码的角度异常处理
- 生成字节码
- Javap 命令的使用
- 基本语法
- 字节码文件
- testTryCatch
- testTryCatchFinally
- testTryWithResource
如果大家对与java的异常使用还有问题或者还不太了解,建议先看一下我之前写的Java异常了解一下基本 的异常处理知识,再看这篇文章。
生成字节码
public class Test27 {public String testTryCatch() {try {int a = 1;int b = 0;return String.valueOf(a / b);} catch (ArithmeticException e) {return "divide 0 ";}}public String testTryCatchFinally() {try {int a = 1;int b = 0;return String.valueOf(a / b);} catch (ArithmeticException e) {return "divide 0 ";}finally {System.out.println("finally");}}public String testTryWithResource() {try {int a = 1;int b = 0;return String.valueOf(a / b);} catch (ArithmeticException e) {return "divide 0 ";}finally {System.out.println("finally");}}}
执行javac命令编译成字节码文件
D:\project\mydemo\src\main\java\com\example\mydemo\test>javac Test27.java
Javap 命令的使用
javap 是 Java 提供的反汇编工具,用于将 Java 字节码文件(.class 文件)反汇编成人类可读的 Java 汇编代码(或者说是 Java 字节码的指令)。这对于理解 Java 编译器生成的字节码、学习 JVM 的工作原理、调试和优化代码都非常有用。
基本语法
javap [options] <classes>
D:\project\mydemo\src\main\java\com\example\mydemo\test>javap -c Test27.class
常用选项
- -c:显示字节码指令(反汇编)。
- -verbose:显示详细信息,包括类、字段、方法的签名和属性。
- -l:显示行号和本地变量表信息。
- -p:显示所有私有成员、受保护成员和默认(包)访问级别的成员。
- -constants:显示静态常量池。
- -classpath
或 -cp :指定类路径。 - -s:显示内部类型签名。
- -public:仅显示公共成员和类。
- -protected:显示公共和受保护成员和类(默认行为)。
- -package:显示公共和包访问级别的成员和类(不加 -p 时默认行为)。
- -private:显示所有成员和类(包括私有成员)。
字节码文件
生成的完整的字节码文件我传上来了,有需要的可以下载,这里我们逐个分析每个方法的字节码。
testTryCatch
public java.lang.String testTryCatch();Code:0: iconst_11: istore_12: iconst_03: istore_24: iload_15: iload_26: idiv7: invokestatic #7 // Method java/lang/String.valueOf:(I)Ljava/lang/String;10: areturn11: astore_112: ldc #15 // String divide 014: areturnException table:from to target type0 10 11 Class java/lang/ArithmeticException
0到3行,是把1跟0这两个常量存到slot里面;4到6是把两个操作数入栈,然后做除法。然后下面是异常表,如果from0 to 10 发生异常,跳转到target11行处理。
testTryCatchFinally
public java.lang.String testTryCatchFinally();Code:0: iconst_11: istore_12: iconst_03: istore_24: iload_15: iload_26: idiv7: invokestatic #7 // Method java/lang/String.valueOf:(I)Ljava/lang/String;10: astore_311: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;14: ldc #23 // String finally16: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V19: aload_320: areturn21: astore_122: ldc #15 // String divide 024: astore_225: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;28: ldc #23 // String finally30: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V33: aload_234: areturn35: astore 437: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;40: ldc #23 // String finally42: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V45: aload 447: athrowException table:from to target type0 11 21 Class java/lang/ArithmeticException0 11 35 any21 25 35 any35 37 35 any
这段字节码,我们主要观察Exception table,很明显
- 0 - 11 行如果发生Class java/lang/ArithmeticException则跳转到21行开始执行。
- 0 - 11行没有发生异常,则跳转到35行开始执行,实际上你仔细看的话,会发现,35行之后是finally的那部分。
- 21 - 25行执行的是catch块里面的语句,执行完之后也会自动跳转到35行执行
- 35 - 37行执行的是把异常class保存起来,以便执行throw的时候能正常抛出去。
testTryWithResource
public java.lang.String testTryWithResource();Code:0: new #31 // class java/io/FileInputStream3: dup4: ldc #33 // String teset6: invokespecial #35 // Method java/io/FileInputStream."<init>":(Ljava/lang/String;)V9: astore_110: ldc #37 // String ok12: astore_213: aload_114: invokevirtual #39 // Method java/io/FileInputStream.close:()V17: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;20: ldc #23 // String finally22: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V25: aload_226: areturn27: astore_228: aload_129: invokevirtual #39 // Method java/io/FileInputStream.close:()V32: goto 4135: astore_336: aload_237: aload_338: invokevirtual #44 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V41: aload_242: athrow43: astore_144: aload_145: invokevirtual #50 // Method java/io/IOException.printStackTrace:()V48: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;51: ldc #23 // String finally53: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V56: goto 7259: astore 461: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;64: ldc #23 // String finally66: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V69: aload 471: athrow72: ldc #37 // String ok74: areturnException table:from to target type10 13 27 Class java/lang/Throwable28 32 35 Class java/lang/Throwable0 17 43 Class java/io/IOException27 43 43 Class java/io/IOException0 17 59 any27 48 59 any59 61 59 any
最后这段字节码我就不带大家一起读了,实际上你自己看就会发现,实际上TryWithResource是语法糖,把之前我们写的一些cath的内容,编译器帮我们添加进去了。编译器自动关闭资源的同时,也帮助我们把异常处理加了进去。如果有疑问的,欢迎评论,私信我。我有时间都会给大家回复解答的。
相关文章:
【Java从入门到放弃 之 从字节码的角度异常处理】
从字节码的角度异常处理 生成字节码Javap 命令的使用基本语法 字节码文件testTryCatchtestTryCatchFinallytestTryWithResource 如果大家对与java的异常使用还有问题或者还不太了解,建议先看一下我之前写的Java异常了解一下基本 的异常处理知识,再看这篇…...
Java虚拟机(JVM)中的元空间(Metaspace)一些关键点的总结
• 元空间的引入:在Java 8中,JVM的内存结构经历了变化,其中方法区被替代为元空间(Metaspace)。元空间用于存储类的元数据信息,包括类的名称、方法、字段等信息。 • 存储位置:与方法区不同&…...
小程序 模版与配置
WXML模版语法 一、数据绑定 1、数据绑定的基本原则 (1)在data中定义数据 (2)在WXML中使用数据 2、在data中定义页面的数据 3、Mustache语法的格式(双大括号) 4、Mustache语法的应用场景 (…...
当大的div中有六个小的div,上面三个下面三个,当外层div高变大的时候我希望里面的小的div的高也变大
问: 当大的div中有六个小的div,上面三个下面三个,当外层div高变大的时候我希望里面的小的div的高也变大 回答: 这时候我们就不能写死六个小的div的高度,否则上下的小的div的间距就会变大,因为他们的高度…...
MySQL——操作
一.库的操作 1.基本操作 创建数据库 create database 数据库名称; 查看数据库 show databases; 删除数据库 drop database 数据库名称; 执行删除之后的结果: 数据库内部看不到对应的数据库 对应的数据库文件夹被删除,级联删除,里面的数据表全部被删…...
Python语法之正则表达式详解以及re模块中的常用函数
正则表达式详解及re模块中的常用函数 概念、作用和步骤 概念: 本身也是一个字符串,其中的字符具有特殊含义,将来我们可以根据这个字符串【正则表达式】去处理其他的字符串,比如可以对其他字符串进行匹配,切分…...
《地球化学》
《地球化学》主要报道近代地球化学, 特别是其主要分支学科, 如岩石地球化学、元素地球化学、有机地球化学、环境地球化学、矿床地球化学、实验地球化学、生物地球化学、天体化学、计算地球化学、分析地球化学、海洋地球化学、沉积地球化学、纳米地球化学、油气地球化学和同位素…...
alpine openssl 编译
./config no-shared --prefix/usr/local/openssl apk add musl-dev gcc g apk add linux-headers ssh root 登录 编辑 SSH 配置文件 打开 SSH 配置文件 /etc/ssh/sshd_config: vi /etc/ssh/sshd_config PermitRootLogin yes...
【AI模型对比】AI新宠Kimi与ChatGPT的全面对比:技术、性能、应用全揭秘
文章目录 Moss前沿AI技术背景Kimi人工智能的技术积淀ChatGPT的技术优势 详细对比列表模型研发Kimi大模型的研发历程ChatGPT的发展演进 参数规模与架构Kimi大模型的参数规模解析ChatGPT的参数体系 模型表现与局限性Kimi大模型的表现ChatGPT的表现 结论:如何选择适合自…...
【C#设计模式(17)——迭代器模式(Iterator Pattern)】
前言 迭代器模式可以使用统一的接口来遍历不同类型的集合对象,而不需要关心其内部的具体实现。 代码 //迭代器接口 public interface Iterator {bool HashNext();object Next(); } //集合接口 public interface Collection {Iterator CreateIterator(); } //元素迭…...
二、部署docker
二、安装与部署 2.1 安装环境概述 Docker划分为CE和EE,CE为社区版(免费,支持周期三个月),EE为企业版(强调安全,付费使用)。 Docker CE每月发布一个Edge版本(17.03&…...
FFmpeg 4.3 音视频-多路H265监控录放C++开发十九,ffmpeg封装
封装就是将 一个h264,和一个aac文件重新封装成一个mp4文件。 这里我们的h264 和 aac都是来源于另一个mp4文件,也就是说,我们会将 in.mp4文件解封装成一路videoavstream 和 一路 audioavstream,然后 将这两路的 avstream 合并成一…...
ML 系列:第 39 节 - 估计方法:最大似然估计 (MLE)
目录 一、说明 二、什么是最大似然估计 (MLE)? 2.1 理解公式 2.2 MLE 的定义 2.3 我们何时使用 MLE? 三、结论 一、说明 在统计学领域,我们经常需要根据观察到的数据估计统计模型的参数。为此目的广泛使用的两种关键方法是最大似然估计 ( MLE…...
Linux 权限管理:用户分类、权限解读与常见问题剖析
🌟 快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。🌟 🚩用通俗易懂且不失专业性的文字,讲解计算机领域那些看似枯燥的知识点🚩 目录 💯L…...
网络原理之 UDP 协议
目录 1. UDP 协议报文格式 2. UDP 的特点 (1) 无连接 (2) 不可靠 (3) 面向数据报 (4) 全双工 3. 基于 UDP 的应用层协议 前文是:UDP 的使用 首先了解一下基础知识: 1. UDP 协议报文格式 传输层最重要的协议有两个,一个是 TCP&#x…...
并发框架disruptor实现生产-消费者模式
Disruptor是LMAX公司开源的高性能内存消息队列,单线程处理能力可达600w订单/秒。本文将使用该框架实现生产-消费者模式。一、框架的maven依赖 <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --><dependency><groupId>com.lmax<…...
【Vivado】xdc约束文件编写
随手记录一下项目中学到的约束文件编写技巧。 时序约束 创建生成时钟 参考链接: Vivado Design Suite Tcl Command Reference Guide (UG835) Vivado Design Suite User Guide: Using Constraints (UG903) 通过Clocking Wizard IP创建的时钟(MMCM或…...
Redis使用场景-缓存-缓存雪崩
前言 之前在针对实习面试的博文中讲到Redis在实际开发中的生产问题,其中缓存穿透、击穿、雪崩在面试中问的最频繁,本文加了图解,希望帮助你更直观的了解缓存雪崩😀 (放出之前写的针对实习面试的关于Redis生产问题的博…...
概率论相关知识随记
作为基础知识的补充,随学随记,方便以后查阅。 概率论相关知识随记 期望(Expectation)期望的定义离散型随机变量的期望示例:掷骰子的期望 连续型随机变量的期望示例:均匀分布的期望 期望的性质线性性质期望的…...
【PlantUML系列】序列图(二)
目录 一、参与者 二、消息交互顺序 三、其他技巧 3.1 改变参与者的顺序 3.2 使用 as 重命名参与者 3.3 注释 3.4 页眉和页脚 一、参与者 使用 participant、actor、boundary、control、entity 和 database 等关键字来定义不同类型的参与者。例如: Actor&…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
