你永远想不到一个try-catch可以玩出这么多花样(下)

899 阅读2分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

哈喽大家好,我是阿Q!

上文中我们已经总结了finally在代码中必然执行的问题,本文我们就从B哥面试遇到的问题出发,来好好分析一波TCF的效率问题!

TCF 的效率问题

说起TCF的效率问题,我们不得不介绍一下异常表,拿上边的程序来说,反编译class文件后的异常表信息如下:

  • from:代表异常处理器所监控范围的起始位置;
  • to:代表异常处理器所监控范围的结束位置(该行不被包括在监控范围内,是前闭后开区间);
  • target:指向异常处理器的起始位置;
  • type:代表异常处理器所捕获的异常类型;

图中每一行代表一个异常处理器

工作流程:

  1. 触发异常时,JVM会从上到下遍历异常表中所有的条目;
  2. 比较触发异常的行数是否在from-to范围内;
  3. 范围匹配之后,会继续比较抛出的异常类型和异常处理器所捕获的异常类型type是否相同;
  4. 如果类型相同,会跳转到target所指向的行数开始执行;
  5. 如果类型不同,会弹出当前方法对应的java栈帧,并对调用者重复操作;
  6. 最坏的情况下JVM需要遍历该线程 Java 栈上所有方法的异常表;

拿第一行为例:如果位于2-4行之间的命令(即try块中的代码)抛出了Class java/lang/Exception类型的异常,则跳转到第8行开始执行。

8: astore_1是指将抛出的异常对象保存到局部变量表中的1位置处

从字节码指令的角度来讲,如果代码中没有异常抛出,TCF的执行时间可以忽略不计;如果代码执行过程中出现了上文中的第6条,那么随着异常表的遍历,更多的异常实例被构建出来,异常所需要的栈轨迹也在生成。该操作会逐一访问当前线程的栈帧,记录各种调试信息,包括类名、方法名、触发异常的代码行数等等。所以执行效率会大大降低。

看到这儿,你是否对TCF有了更加深入的了解呢?下次让你对线面试官,你会五五开吗?

题外篇

阿Q将持续更新java实战方面的文章,感兴趣的可以关注下公众号:阿Q说代码,也可以来技术群讨论问题呦,点赞之交值得深交!