我们工作中常用try...catch来解决程序中出现的异常情况,但是你真的了解它的实现原理吗?今天我就带着大家从字节码层面理解try...catch
一、准备工作
我们首先需要准备好异常类和对应的测试类方便我们观察。
异常类:
public class DivideByZeroException extends Exception {
}
测试类:
public class ExceptionUtil {
static int remainder(int dividend, int divisor) throws DivideByZeroException {
try {
return dividend % divisor;
} catch (ArithmeticException var3) {
throw new DivideByZeroException();
}
}
}
在idea中编译后,使用jclasslib插件即可查看对应的字节码,字节码如下。
0 iload_0
1 iload_1
2 irem
3 ireturn
4 astore_2
5 new #3 <com/haiwang/hotel/exception/DivideByZeroException>
8 dup
9 invokespecial #4 <com/haiwang/hotel/exception/DivideByZeroException.<init> : ()V>
12 athrow
右键点击可以查看字节码的详情。
该字节码可以分为两部分,一部分是对方法的常规处理,另一部分是对异常的处理
常规处理:
0 iload_0//载入参数一
1 iload_1//载入参数二
2 irem//进行取余操作
3 ireturn//返回操作值
异常处理:
4 astore_2//将ArithmeticException的地址压栈
5 new #3 <com/haiwang/hotel/exception/DivideByZeroException>//实例化DivideByZeroException
8 dup//复制异常对象并放入栈顶
9 invokespecial #4 <com/haiwang/hotel/exception/DivideByZeroException.<init> : ()V>//初始化DivideByZeroException
12 athrow//抛出异常的引用
在我们使用try...catch的时候都会生成一个异常表,jvm会查询这个异常表,并抛出对应的异常类。
参考文章:
How the Java virtual machine handles exceptions | InfoWorld
Java SE Specifications