0
点赞
收藏
分享

微信扫一扫

详解 JVM 字节码(9)

今天来看一看字节码中的异常处理表

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 以后进行静态数据校验,


  • new : 创建一个新的对象
  • dup :
public void readFile()
 stack=3, locals=4, args_size=1
  • stack=3:最大深度
  • args_size=1 : 这里在readFile()有一个参数为 this。
  • locals=4 : 局部变量为
    1. this
    2. inputStream
    3. serverSocket
    4. 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语句进行跳转到异常处理的位置。

  • 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 块后。
举报

相关推荐

0 条评论