Java:简述try-catch-finally中return返回
Java:简述try-catch-finally中return返回
- 《》
- 《》
- 《》
- 《》
- 《》
提示:阅读本文章之前可以先阅读《》
java中的 finally关键字通常与 try/catch块一起使用。用来在方法结束前或发生异常时做一些资源释放的操作。虽然看起来很简单,在日常开发中也发现关于 finllay还是有些需要注意的地方。
一 . finally 语句块一定会执行吗?
很多人都认为 finally语句块是肯定要执行的,比如下面的代码,只要进入了 try/catch块,不管有没有异常,都会执行 finllay块。
public static void main(String[] args) { System.out.println(test()); } public static int test(){ try { System.out.println("try block"); int i = 1 / 0; return 0; } finally { System.out.println("finally block"); } }
运行代码输出 :
try block finally block Exception in thread "main" java.lang.ArithmeticException: / by zero
但是答案是否定的,我们先来看下面这个例子:
public static void main(String[] args) { System.out.println(test()); } public static int test(){ try { System.out.println("try block"); System.exit(0); return 0; } finally { System.out.println("finally block"); } }
运行代码输出 :
try block
我们在 try语句块中执行了 System.exit (0)语句,终止了 Java 虚拟机的运行, finally语句块就没有执行。
其实,在下述4种特殊情况时,finally块都不会被执行: 1)在finally语句块中发生了异常。 2)在前面的代码中用了System.exit()退出程序。 3)程序所在的线程死亡。 4)关闭CPU。
二 . 如果执行了finally,函数返回值问题
我们先来看下面这个例子:
public static void main(String[] args) { System.out.println(test()); } public static int test(){ try { System.out.println("try block"); int i = 1 / 0; return 0; } catch (Exception e) { System.out.println("catch block"); return 1; } finally { System.out.println("finally block"); return 2; } }
运行代码输出 :
try block catch block finally block 2
对于上面的代码,相信大部分人都能知道输出值是 2,打印结果也确实是 2,就算把 int i = 1 / 0这一行注释掉,打印结果也是 2。
所以在这里我们可以下结论 : finally里的 return语句会把 try/catch块里的 return语句效果给覆盖掉。
假如我们不在 finally中 return,结果会怎样?我们再看看下面的例子 :
public static void main(String[] args) { System.out.println(test()); } public static int test(){ int i = 999; try { System.out.println("try block"); i = 1 / 0; return i; } catch (Exception e) { System.out.println("catch block"); i = 100; return i; } finally { System.out.println("finally block"); i = 200; } }
打印结果是 :
try block catch block finally block 100
虽然调用了 finllay改变了i的值,但是最后输出还是 100,为什么呢?
对于这种情况我的理解就是在 return的时候会把返回值压入栈,并把返回值赋值给栈中的局部变量, 最后把栈顶的变量值作为函数返回值。所以在 finally中的返回值就会覆盖 try/catch中的返回值,如果 finally中不执行 return语句,在 finally中修改返回变量的值,不会影响返回结果。下图为字节码文件中的部分内容:
参考: