[关闭]
@linux1s1s 2019-02-15T13:05:10.000000Z 字数 2785 阅读 1837

关于try、catch、finally小结

Java 2015-11


对于一般常规例子,我们直接给出小结

(假设有返回值)

对于上面给出的小结,我们来个例子佐证一下

  1. public class TryCatchFinnal {
  2. public static final String getName() {
  3. String name = "";
  4. try {
  5. name = "try";
  6. return name;
  7. } catch (Exception e) {
  8. name = "catch";
  9. return name;
  10. } finally {
  11. name = "finally";
  12. }
  13. }
  14. }

测试用例

  1. public class TestCase {
  2. public static void main(String[] args) {
  3. System.out.println(TryCatchFinnal.getName());
  4. }
  5. }

运行结果
此处输入图片的描述

哇偶,根据上面的小结,是不是很奇迹为啥返回结果不是 finally ?
为了一探究竟,我们直接看编译出来的字节码好了

  1. public static final java.lang.String getName();
  2. Code:
  3. Stack=1, Locals=4, Args_size=0
  4. 0: ldc #16; //String
  5. 2: astore_0
  6. 3: ldc #18; //String try
  7. 5: astore_0
  8. 6: aload_0
  9. 7: astore_3
  10. 8: ldc #20; //String finally
  11. 10: astore_0
  12. 11: aload_3
  13. 12: areturn
  14. 13: astore_1
  15. 14: ldc #22; //String catch
  16. 16: astore_0
  17. 17: aload_0
  18. 18: astore_3
  19. 19: ldc #20; //String finally
  20. 21: astore_0
  21. 22: aload_3
  22. 23: areturn
  23. 24: astore_2
  24. 25: ldc #20; //String finally
  25. 27: astore_0
  26. 28: aload_2
  27. 29: athrow
  28. Exception table:
  29. from to target type
  30. 3 8 13 Class java/lang/Exception
  31. 3 8 24 any
  32. 13 19 24 any
  33. LineNumberTable:
  34. line 5: 0
  35. line 8: 3
  36. line 9: 6
  37. line 15: 8
  38. line 9: 11
  39. line 10: 13
  40. line 12: 14
  41. line 13: 17
  42. line 15: 19
  43. line 13: 22
  44. line 14: 24
  45. line 15: 25
  46. line 16: 28
  47. LocalVariableTable:
  48. Start Length Slot Name Signature
  49. 3 27 0 t Ljava/lang/String;
  50. 14 10 1 e Ljava/lang/Exception;
  51. StackMapTable: number_of_entries = 2
  52. frame_type = 255 /* full_frame */
  53. offset_delta = 13
  54. locals = [ class java/lang/String ]
  55. stack = [ class java/lang/Exception ]
  56. frame_type = 74 /* same_locals_1_stack_item */
  57. stack = [ class java/lang/Throwable ]

通过字节码,我们发现,在try语句的return块中,return 返回的引用变量(t 是引用类型)并不是try语句外定义的引用变量t,而是系统重新定义了一个局部引用t’,这个引用指向了引用t对应的值,也就是try ,即使在finally语句中把引用t指向了值finally,因为return的返回引用已经不是t ,所以引用t的对应的值和try语句中的返回值无关了。

所以我们有必要补充一下

  1. public class TryCatchFinnal {
  2. public static final String getName() {
  3. String name = "";
  4. try {
  5. name = "try";
  6. Integer.parseInt(null);
  7. return name;
  8. } catch (Exception e) {
  9. name = "catch";
  10. return name;
  11. } finally {
  12. name = "finally";
  13. }
  14. }
  15. }

此处输入图片的描述

而如果直接在finally语句块中返回这个值,显而易见返回值是finally。

  1. public class TryCatchFinnal {
  2. @SuppressWarnings("finally")
  3. public static final String getName() {
  4. String name = "";
  5. try {
  6. name = "try";
  7. Integer.parseInt(null);
  8. return name;
  9. } catch (Exception e) {
  10. name = "catch";
  11. return name;
  12. } finally {
  13. name = "finally";
  14. return name;
  15. }
  16. }
  17. }

此处输入图片的描述

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注