angular5 如何抛异常_从字节码开始讲JVM是如何实现抛异常和catch异常的(下)

前面一篇文章介绍了Java中异常的try-catch-final的原理(从字节码开始讲JVM是如何进行Java异常处理的(上)),今天我们就进一步分析一下JVM是如何实现它的。

JVM是如何抛异常的

要想了解try-catch-final的实现原理,那么就必须要先知道JVM是如何抛出异常信息的。以如下的代码为例来分析一下:

cce7721cfe8bc1425312311e243d1440.png

这段代码通过javap命令得到如下信息

2a1189fe5caa0cf6d44731d9cdb8e4a7.png

代码很简单,对应的字节码也是非常的简单。看指令名称我们就可以很快的找到对应抛异常的指令:athrow指令。

athrow指令之前就是new 一个exception的代码,之后就是catch的代码了(从异常信息表里也能印证)。

知道了JVM是通过athrow指令来抛出异常的,接下来我们就看看JVM是如何实现athrow指令的。

athrow指令的实现原理

以JDK9为例,我们在JVM源码中全局搜索athrow,能够得到如下的信息:

603144ccb8a4b52ba401e79aa915fe88.png

从文件名就知道,athrow在不同的平台具有不同的实现。其实他们的实现基本大同小异,最终都是会跳到Interpreter::throw_exception_entry()返回的抛异常入口代码。

throw_exception_entry()返回的是指令模板(什么是JVM的指令模板呢?以后有机会再介绍),实现如下:

72d2c75bf22a7e66e0a1b14399296f82.png

上面的代码主要实现的逻辑为:

a82b17624120d2e1fe1ca6faa756bb31.png

说明:

  • 显然查找异常处理代码是整个过程最为重要的部分,它是通过call_VM指令完成的,我们等会进一步说明。
  • 查找到的异常处理代码是通过jmp指令跳转的,所以处理完是不会回到原位的,这也就实现了异常后面的代码是不会被处理的。

至此,JVM抛异常的实现原理就基本介绍完了,接下来介绍JVM是如何实现对异常的catch的。

JVM是如何实现catch异常的

知道了JVM是如何实现throw的,那么catch的实现过程也就很好理解了。我们知道Java方法抛出的异常catch和finally语句块都会被记录在异常信息表中,并且它们两的实现上并没有本质的区别。上面也介绍了JVM在实现抛异常的时候,会先去查找异常的处理代码位置,JVM就是在这个异常信息表中查找的。

JVM查找异常处理handler的代码比较多就不贴全部代码了,主要实现过程如下图所示:

9bf6a21c25a4a0dfdf874418154ab657.png

其中最为关键的handler查找代码:

ae5cdc2e381988882e40218b398a4834.png

这段代码会循环遍历异常信息表,然后找到当前执行位置在起始和结束位置之间的那一项,接下来判断这一项是否能够处理需要处理的exception。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值