通过字节码分析Java异常处理机制
在上一次【https://www.cnblogs.com/webor2006/p/9691523.html】初步对异常表相关的概念进行了了解,先来回顾一下:
其源代码也贴一下:

下面来看一下jclasslib关于这个test()的信息:

咱们重点来看一下Code信息,如下:

其实也就是对应于javap -verbose看到的字节码信息,咱们一行行的跟源代码进行比对一下:

点击看一下new的助字符的官方解释:

实际对应源码就是:


查看一下官网的解释:


查看一下解释:

回到咱们这句话其意思就是将常量“test.txt”推到常量池中使得能构造出FileInputStream对象。

这个我们之前了解过,这里再看一下官网的解释:

回到咱们这句话意思就是调用了父类的构造方法,因为创建子类其父类肯定得要先被创建才行。


也就是将"is"存到局部变量当中,所以前面的这些助记符就对应这样一个句源码,如下:
对应于

类似的下面这一行源代码其实对应的助字符差不多,如下:

下面也来瞧一下:
new一个对象:

跟之前一样,将最顶层操作数栈的值进行复制,往下:

其中sipush官网解释如下:
这里有一个细节需要注意:源代码中的999其实是一个int类型的,如下:
但是在字节码中999其实是属于short类型范围之内,所以是当一个short类型处理了。

调用ServerSocket的构造方法及父类的,不多说比较容易理解。

看一下它官网的解释:

也就是将引用赋给了serverSocket变量。

官网的解释:





其实对于方法的调用方式都是基于操作栈的,所以有大量的入栈和出栈的一些操作在里面的。

发现这对应于代码:
由于catch块中没有写代码,所以直接就到了finally了。


也就是finally这个关键字嘛。

调用打印实例方法。
接下来发现有大量的goto助记符:
也就是对于异常在字节码的表现形式是通过goto来将整个执行进行中断的,为了能理解这里面的goto,此时需要先分析一下异常表信息,如下:

其中可以整体看到“Catch Type”这行,刚好跟咱们捕获的异常能对应上,如下:
其中还有最后一个:

其中理论依据为:
下面具体来看一下:

发现Start PC和End PC都是从0到26,先来回顾一下这两个的含义:
也就是表示:

其实对应于源代码就是try的部分,如下:

这段代码抛出任何异常都会有相应的异常表项来处理,咱们一一来看一下:

也就是说如果代码发现了FileNotFoundException异常时,则会由37这个位置的Handler PC来处理异常,那37对应于哪呢?

而astore_1表示:
那如何理解呢?来看下源代码:

很明显当生成异常时会将异常对象赋值给这个ex,所以就会有这样的一个引用赋值操作,由于这个catch块中没有写任何代码,所以就立马就执行到了finally块了,也就是对应于这段助记符:

最后又有一个goto了,如下:

第一个异常的整个字节码流程分析完之后,其它两个就基本类似了,咱们来过一遍:

当发生异常则会跳到49的Handler PC,如下:

接着再看第三个异常:

然后会跳到61,看一下,一样的套路:

好了对于咱们自己捕获的异常的内部处理机制已经非常之清楚了,剩最后一种异常情况下,如下:

从程序角度照理应该是Exception已经包含所有可以捕获的异常了,但是从字节码角度并不这样认为,所以这也是为啥会有这么一个异常的情况出现,表示处理上面咱们手动捕获的之外不可能处理的异常,这是编译器自动为我们生成出来的,咱们来看一下73是啥:

只是其中发现了一个athrow,这是个什么东东:

至此,咱们就彻底把异常机制相关的东东完完整整的分析完了,下面来总结一下:
Java字节码对于异常的处理方式:
1、统一采用异常表的方式来对异常进行处理。
2、在之前的JDK 1.4.2之前的版本中并不是使用异常表的方式来对异常进行处理的,而是采用特定的指令方式。【了解既可】
3、当异常处理存在finally语句块时,现代化的JVM采取的处理方式是将finally语句块的字节码批接到每一个catch块后面,换句话说,程序中有多少个catch块,就会在每一个catch块后面重复多少个finally语句块的的字节码。从字节码就可以得知:
关于异常表就了解到这,接下来了解另外一个信息,如下:

根据之前的了解,我们也知道这个属性主要是描述字节码的位置对应源代码的行号,便于debug,如下:

下面来一一细看一下:

字节码0处对应源代码13行,瞅一下:


其中的Start PC是指代码字节码的起始位置,刚好是对应的。
继续:

字节码10对应源代码14,看一下:


完全能对应上,继续再挑一个看,由于规则是一样的,就没必要完全一个个对了,知道个大概作用就成:

字节码49对应源代码18:


所以通过这个就可以将字节码跟源代码对应起来。
最后再来看一下它:

发现jclasslib中只有3个,而之前在javap -verbose中看到的是有4个,回忆下:

因为目前jcalsslib打开的是一个静态的class,并不知道是否抛出异常,所以静态的情况下就只能看到3个局部变量,javap -verbose上看到的是最大可以有4个局部变量,也就是一旦运行抛异常了那最终就有4个局部变量啦,没毛病的!
通过字节码分析Java异常处理机制的更多相关文章
- 通过字节码分析java中的switch语句
在一次做题中遇到了switch的问题,由于对switch执行顺序的不了解,在这里简单的通过字节码的方式理解一下switch执行顺序(题目如下): public class Ag{ static pub ...
- 通过字节码分析Java方法的静态分派与动态分派机制
在上一次[https://www.cnblogs.com/webor2006/p/9723289.html]中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这 ...
- 透过字节码分析java基本类型数组的内存分配方式。
我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...
- 透过字节码分析Java动态代理机制。
一.创建动态代理代码 1.创建接口 public interface Subject { void request(); } 2.创建接口实现类 public class RealSubject im ...
- Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)
前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...
- [五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的
Launcher启动类 本文是双亲委派机制的源码分析部分,类加载机制中的双亲委派模型对于jvm的稳定运行是非常重要的 不过源码其实比较简单,接下来简单介绍一下 我们先从启动类说起 有一个Lau ...
- Java字节码分析
目录 Java字节码分析 查看字节码详细内容 javap 实例分析 Java字节码分析 对于源码的效率,但从源码来看有时无法分析出准确的结果,因为不同的编译器版本可能会将相同的源码编译成不同的字节码, ...
- 如何正确使用Java异常处理机制
文章来源:leaforbook - 如何正确使用Java异常处理机制作者:士别三日 第一节 异常处理概述 第二节 Java异常处理类 2.1 Throwable 2.1.1 Throwable有五种构 ...
- 通过字节码分析this关键字以及异常表的重要作用
在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序: 接着编译来看用javap -verbose来查看一下它的字节码信息: xion ...
随机推荐
- SVN安装使用【转】
SVN使用教程总结 SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Sub ...
- 【馨儿收藏】群星《2019最新好听DJ舞曲精选》全系列【WAV/在线/百度】(持续更新)
本人作为一名音乐发烧友,一直喜欢追求无损音乐,平时在开发编程无聊的时候,希望享受音乐的过程,追求完美,我这边整理了一系列的比较不错,新的好听的无损音乐,希望大家能够喜欢. [馨儿收藏]群星<20 ...
- 最新 房天下java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.房天下等10家互联网公司的校招Offer,因为某些自身原因最终选择了房天下.6.7月主要是做系统复习.项目复盘.LeetCo ...
- 软件测试开发人员需要掌握的一些基本数据结构算法(php编写)
一:冒泡排序算法 冒泡排序(Bubble Sort)算法是一种典型的交换排序算法,通过两两数据交换进行排序.如果有n个数,则要进行n-1趟比较,在第1趟比较中要进行n-1次两两比较,在第j趟比较 ...
- Python 实现二分查找(递归版)
二分查找 为什么使用二分查找: python中的列表,一般取值为遍历这个列表,直到取到你想要的值,但是如果你的列表是一个有着百万元素的列表呢,那样for循环遍历列表就会很慢,可能会循环几十万次,才能找 ...
- Python进入后台界面(admin)设定
前言 用过Django框架的童鞋肯定都知道,在创建完Django项目后,每个app下,都会有一个urls.py文件,里边会有如下几行: ※特别要注意下面标红颜色的部分[] 一般情况下不需要修改什么东西 ...
- FineReport工具
PostgreSQL链接问题: 正常安装FineReport工具和PostgreSQL数据库之后,在FineReport工具当中链接数据库显示连接失败的原因是因为FineReport安装包里面没有Po ...
- java日志框架系列(6):logback框架encoder详解
1.Encoder 1.encoder功能 Encoder 负责两件事,一是把事件转换为字节数组,二是把字节数组写入输出流. 注意:在logback 0.9.19 版之前没有 encoder. 在之前 ...
- Firefox在新标签页打开“书签”和“搜索栏”(无需插件)
转自 初来灬炸到的博客 前言 每次打开书签前,都需要创建新标签页. 每次搜索前,都需要创建新标签页. 这个真滴很麻烦.下面介绍的方法非常简单,不需要任何插件,通过修改浏览器参数即可. 名词 设置 ...
- 【Scratch】编程?一节课就教会你!其实我们不用一个个学习如何使用代码。
第199篇文章 老丁的课程 在很多教程里面,大家都喜欢把模块拿出来一个个讲述其功能. 这样做的好处是,可以把每个代码模块的功能讲的很清楚.但最最讨厌的问题也随之而来…… 举个例子,当你学习英语的时候, ...