jvm
今天来看一看字节码中的异常处理表.
- public class ReadFileHelper {
- public void readFile(){
- try {
- InputStream inputStream = new FileInputStream("test.txt");
- ServerSocket serverSocket = new ServerSocket(4200);
- serverSocket.accept();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }finally {
- System.out.println("call finally method...");
- }
- }
- }
StackMap Table 在 JDK 1.7 以后进行静态数据校验,
code 助记符
new : 创建一个新的对象
- dup :
- public void readFile()
- stack=3, locals=4, args_size=1
stack=3: 最大深度
args_size=1 : 这里在 readFile() 有一个参数为 this.
locals=4 : 局部变量为
- this
- inputStream
- serverSocket
- ex
虽然有 3 catch 来捕获对象, 但是只是走一个 catch 所以异常对象只会一个作为局部变量.
每一个 exception_table(异常处理表) 表项由 start_pc, end_pc, handler_pc , catch_type 组成.
start_pc 和 end_pc 表示在 code 数组中的从 start_pc 到 end_pc 处 (包括 start_pc, 不包含 end_pc) 的指令抛出的异常会由这个表项来处理
handler_pc 表示处理异常的代码的开始处. catch_type 表示会被处理的异常类型, 指向常量池里的一个异常类. 当 catch_type 为 0 时, 表示处理所有异常.
发生异常会使用 goto 语句进行跳转到异常处理的位置.
jclasslib
code
new : 创建对象
dup : 复制操作栈的顶层然后入栈
ldc : 将常量池获取信息
inovkespecial : 调用父类构造方法
astore_1 : new FileInputStream 创建对象复制给 inputStream 局部变量进行存储
下面同上
pop 从栈进行弹出
getstatic 调用 System.out.Print 静态方法
异常表
异常表最后一个 any 表示处理以上列出异常以外, 都有此异常处理来处理.
0 -26 出现了 FileNotFoundException 异常就会转到 37 进行处理, astore_1 赋值给局部变量.
0 - 26 如果出现对应 IOException 就会跳转 37 进行处理, astore_1 赋值给局部变量.
字节码中 Java 对异常的处理
统一采用异常表的方法来对异常进行处理
当异常处理存在 finally 语句块, 现在 JVM 将 finally 的语句块字节码拼接到每一个 catch 块后.
来源: http://www.jianshu.com/p/abfdc378bdd8