Java:简述try-catch-finally中return返回
- 《Java:详解Java中的异常(Error与Exception)》
- 《Java:简述Java中的自定义异常》
- 《Java:简述throw-throws异常抛出》
- 《Java:简述try-catch-finally异常捕获》
- 《Java:简述try-catch-finally中return返回》
提示:阅读本文章之前可以先阅读《Java:简述try-catch-finally异常捕获》
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中修改返回变量的值,不会影响返回结果。下图为字节码文件中的部分内容: