首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Java字节码角度分析:异常_finally——提升硬实力10

  • 25-03-07 20:01
  • 3498
  • 9392
blog.csdn.net

在前面的文章中,有详细地介绍java字节码相关的知识,有兴趣的可以提前了解一下。

1.Java字节码的一段旅行经历——提升硬实力1

2.Java字节码角度分析a++ ——提升硬实力2

3.Java字节码角度分析条件判断指令 ——提升硬实力3

4.Java字节码角度分析循环控制 ——提升硬实力4

5.Java字节码角度分析判断结果 ——提升硬实力5

6.Java字节码角度分析构造方法 ——提升硬实力6

7.Java字节码角度分析方法调用 ——提升硬实力7

8.Java字节码角度分析多态原理 ——提升硬实力8

9.Java字节码角度分析异常处理——提升硬实力9

 


从字节码角度分析 异常_finally

示例代码如下:

  1. // 从字节码角度分析:异常_finally
  2. public class T16_ByteAnalyseFinally {
  3. public static void main(String[] args) {
  4. int i = 0;
  5. try {
  6. i = 10;
  7. } catch (Exception e){
  8. i = 20;
  9. } finally {
  10. i = 30;
  11. }
  12. }
  13. }

上述代码通过:javap -v T16_ByteAnalyseFinally.class进行反编译,得到如下字节码。

  1. public static void main(java.lang.String[]);
  2. descriptor: ([Ljava/lang/String;)V
  3. flags: ACC_PUBLIC, ACC_STATIC
  4. Code:
  5. stack=1, locals=4, args_size=1
  6. 0: iconst_0
  7. 1: istore_1 // 0 -> i
  8. 2: bipush 10 // try ----------------------
  9. 4: istore_1 // 10 -> i |
  10. 5: bipush 30 // finally |
  11. 7: istore_1 // 30 -> i |
  12. 8: goto 27 // return -------------------
  13. 11: astore_2 // catch Exception -> e -----
  14. 12: bipush 20 // |
  15. 14: istore_1 // 20 -> i |
  16. 15: bipush 30 // finally |
  17. 17: istore_1 // 30 -> i |
  18. 18: goto 27 // return -------------------
  19. 21: astore_3 // catch any -> slot 3 ------
  20. 22: bipush 30 // finally |
  21. 24: istore_1 // 30 -> I |
  22. 25: aload_3 // <- slot 3 |
  23. 26: athrow // throw -------------------
  24. 27: return
  25. Exception table:
  26. from to target type
  27. 2 5 11 Class java/lang/Exception
  28. 2 5 21 any // 剩余的异常类型,比如 Error
  29. 11 15 21 any // 剩余的异常类型,比如 Error
  30. LineNumberTable: ...
  31. LocalVariableTable:
  32. Start Length Slot Name Signature
  33. 12 3 2 e Ljava/lang/Exception;
  34. 0 28 0 args [Ljava/lang/String;
  35. 2 26 1 i I
  36. StackMapTable: ...

上述说明:

  1. 可以看到 finally 中的代码被复制了 【3】 份,分别放入 try 流程, catch 流程以入 catch 剩余的异常类型流程

面试题:finally 出现了 return

代码示例如下:

  1. // 从字节码角度分析:finally 出现了 return
  2. public class T17_ByteAnalyseFinallyReturn {
  3. public static void main(String[] args) {
  4. int result = test();
  5. System.out.println(result);
  6. }
  7. public static int test() {
  8. try {
  9. return 10;
  10. } finally {
  11. return 20;
  12. }
  13. }
  14. }

先问问自己:上面的题目输出什么?

上述代码通过:javap -v T17_ByteAnalyseFinallyReturn.class进行反编译,得到如下字节码。

  1. public static int test();
  2. descriptor: ()I
  3. flags: ACC_PUBLIC, ACC_STATIC
  4. Code:
  5. stack=1, locals=2, args_size=0
  6. 0: bipush 10 // <- 10 放入栈顶
  7. 2: istore_0 // 10 -> slot 0 (从栈顶移除了)
  8. 3: bipush 20 // <- 20 放入栈顶
  9. 5: ireturn // 返回栈顶 int(20)
  10. 6: astore_1 // catch any -> slot 1
  11. 7: bipush 20 // <- 20 放入栈顶
  12. 9: ireturn // 返回栈顶 int(20)
  13. Exception table:
  14. from to target type
  15. 0 3 6 any
  16. LineNumberTable: ...
  17. StackMapTable: ...

上述说明: 

  1. 由于 finally 中的 ireturn 被插入了所有可能的流程,因此返回结果肯定以 finally 为准
  2. 至于字节码中第2行,似乎没啥用,且留个伏笔,看下个例子
  3. 跟上例中的 finally 相比,发现没有 athrow 了,这告诉我们:如果在 finally 中出现了 return,会吞掉异常!可以试一下下面的代码。

下面的代码会发生除0异常,但 finally 后面有 return 语句,会将除0异常(ArithmeticException: / by zero)吞掉。

  1. // 从字节码角度分析:finally 出现了 return
  2. public class T18_ByteAnalyseFinallyReturn2 {
  3. public static void main(String[] args) {
  4. int result = test();
  5. System.out.println(result);
  6. }
  7. public static int test() {
  8. try {
  9. int i = 1 / 0;
  10. return 10;
  11. } finally {
  12. return 20;
  13. }
  14. }
  15. }

面试题2:finally 对返回值影响

同样问问自己,下面的题目输出什么?

  1. // 从字节码角度分析:finally 出现了 return
  2. public class T19_BateAnalyseFinallyReturn3 {
  3. public static void main(String[] args) {
  4. int result = test();
  5. System.out.println(result);
  6. }
  7. public static int test() {
  8. int i = 10;
  9. try {
  10. return i;
  11. } finally {
  12. i = 20;
  13. }
  14. }
  15. }

上述代码通过:javap -v T19_BateAnalyseFinallyReturn3.class进行反编译,得到如下字节码。

  1. public static int test();
  2. descriptor: ()I
  3. flags: ACC_PUBLIC, ACC_STATIC
  4. Code:
  5. stack=1, locals=3, args_size=0
  6. 0: bipush 10 // <- 10 放入栈顶
  7. 2: istore_0 // 10 -> i
  8. 3: iload_0 // <- i(10)
  9. 4: istore_1 // 10 -> slot 1, 暂存至 slot 1, 目的是为了固定返回值
  10. 5: bipush 20 // <- 20 放入栈顶
  11. 7: istore_0 // 20 -> i
  12. 8: iload_1 // <- slot 1(10) 载入 slot 1 暂存的值
  13. 9: ireturn // 返回栈顶的 int(10)
  14. 10: astore_2
  15. 11: bipush 20
  16. 13: istore_0
  17. 14: aload_2
  18. 15: athrow
  19. Exception table:
  20. from to target type
  21. 3 5 10 any
  22. LineNumberTable: ...
  23. LocalVariableTable:
  24. Start Length Slot Name Signature
  25. 3 13 0 i I

上述说明: 

  1. return i; 对应的字节码为  istore_1   目的是将 10 存入局部变量表1号槽位,目的是为了固定返回值;
  2. 只要不在 finally 代码块中 return ,其异常是不会被吞掉;

总结:

  1. 可以看到 finally 中的代码被复制了 N 份,分别放入 try 流程, catch 流程以入 catch 剩余的异常类型流程
  2. 由于 finally 中的 ireturn 被插入了所有可能的流程,因此返回结果肯定以 finally 为准
  3. 如果在 finally 中出现了 return,会吞掉异常!这是非常危险的操作,意味着程序出错了也不会报错!

所以,日常代码中:不能在 finally 代码块中进行 return 操作。另外我们在阿里巴巴开发手册中也能找到类似的说明,如下:

 


文章最后,给大家推荐一些受欢迎的技术博客链接:

  1. Hadoop相关技术博客链接
  2. Spark 核心技术链接
  3. JAVA相关的深度技术博客链接
  4. 超全干货--Flink思维导图,花了3周左右编写、校对
  5. 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
  6. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  7. 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂

 


欢迎扫描下方的二维码或 搜索 公众号“10点进修”,我们会有更多、且及时的资料推送给您,欢迎多多交流!

                                           

       

 

注:本文转载自blog.csdn.net的不埋雷的探长的文章"https://blog.csdn.net/weixin_32265569/article/details/108025367"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top