【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&…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...