写点什么

异常捕获中 finally 和 return 的用法

作者:自由呼吸
  • 2022-11-29
    北京
  • 本文字数:1993 字

    阅读完需:约 7 分钟

 try..catch...finally 结构中,当 try 或 catch 语句块中带有 return 时,程序的执行顺序会是什么样?

​1、验证 finally 和 return 的执行顺序

1.1、try 语句正常执行


public class Circle {
public static void main(String[] args) { int p = Circle.getint(1); System.out.println(p); } public static int getint(int c) { int a = 0; try{ a = 6/c; return a; }catch(Exception e){ System.out.println("error"); return a; }finally{ System.out.println("finally"); } }}
复制代码


小结:加上 debug 后进行调试,可以查看程序运行过程:


程序进入 try 后,执行到 return 时,并没有直接返回,而是又进入到 finally,然后再回到 try 语句块中的 return,最终返回。


1.2、try 语句执行异常


public class Circle {
public static void main(String[] args) { int p = Circle.getint(0); System.out.println(p); } public static int getint(int c) { int a = 0; try{ a = 6/c; return a; }catch(Exception e){ System.out.println("error"); return a; }finally{ System.out.println("finally"); } }}
复制代码

小结:加上 debug 后进行调试,可以查看程序运行过程:


程序进入 try 后,遇到异常,跳转到 catch 块中,当执行到 return 时,也没有直接返回,又进入到 finally,然后再回到 catch 语句块中的 return,最终返回。


由此可见:

当 try 或 catch 块中带有 return 语句时,和没有 return 时一样,都在执行完本块所有语句后,跳转到 finally 中,当执行完 finally 语句块后,才返回最终执行结果。这样应该也是为了确保 finally 中的资源被正常关闭,不会因为 return 而出现资源被继续占用的情况。


疑问:当 finally 中对 return 的返回值进行了修改时,能否生效?


2、通过 finally 块修改返回变量

2.1、基本数据类型,try 语句正常执行


public class Circle {
public static void main(String[] args) { int p = Circle.getint(2); System.out.println(p); } public static int getint(int c) { int a = 0; try{ a = 6/c; return a; }catch(Exception e){ a = 10; System.out.println("error"); return a; }finally{ a = 7; System.out.println("finally"); } }}
复制代码

返回结果为

finally

3


小结:虽然在 finally 中对基本数据类型的变量进行了修改,但并没有生效,最终返回的还是带有 return 语句 try 块中的执行结果。


2.2、基本数据类型,try 语句执行异常


public class Circle {
public static void main(String[] args) { int p = Circle.getint(0); System.out.println(p); } public static int getint(int c) { int a = 0; try{ a = 6/c; return a; }catch(Exception e){ a = 10; System.out.println("error"); return a; }finally{ a = 7; System.out.println("finally"); } }}
复制代码

返回结果为

error

finally

10


小结:虽然在 finally 中对基本数据类型的变量进行了修改,但并没有生效,最终返回的还是带有 return 语句 catch 块中的执行结果。


2.3、引用数据类型,try 语句执行正常


import java.util.Arrays;
public class Circle { public static int[] getintarr(int c) { int[] arr = {1, 3, 5}; try{ arr[0] = 7/c; return arr; }catch(Exception e){ arr[0] = 10; System.out.println("error"); return arr; }finally{ arr[0] = 9; System.out.println("finally"); } } public static void main(String[] args) { int[] pp = Circle.getintarr(2); System.out.println(Arrays.toString(pp)); } }
复制代码

返回结果为

finally

[9, 3, 5]


小结:在 finally 中对引用数据类型的变量进行了修改,可以看到在最终的返回结果中,数组第一个元素是在 finally 修改的数据。


2.4、引用数据类型,try 语句执行异常


import java.util.Arrays;
public class Circle { public static int[] getintarr(int c) { int[] arr = {1, 3, 5}; try{ arr[0] = 7/c; return arr; }catch(Exception e){ arr[0] = 10; System.out.println("error"); return arr; }finally{ arr[0] = 9; System.out.println("finally"); } } public static void main(String[] args) { int[] pp = Circle.getintarr(0); System.out.println(Arrays.toString(pp)); } }
复制代码

返回结果为

error

finally

[9, 3, 5]


小结:在 finally 中对引用数据类型的变量进行了修改,可以看到在最终的返回结果中,数组第一个元素是在 finally 修改的数据。

3、结论

A、无论 try 语句是否存在 return 语句,finally 都会被执行到。


B、当 return 返回的是基本数据类型时,在 finally 中无法修改。


C、当 return 返回的是引用数据类型时,在 finally 中可以修改。


发布于: 刚刚阅读数: 4
用户头像

自由呼吸

关注

还未添加个人签名 2018-12-20 加入

还未添加个人简介

评论

发布
暂无评论
异常捕获中finally和return的用法_Java_自由呼吸_InfoQ写作社区