异常捕获中finally和return的用法
在一次面试中,有人提到 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、通过以上实验可以看到,可以得到如下三个结论
1、无论 try 语句是否存在 return 语句,finally 都会被执行到。
2、当 return 返回的是基本数据类型时,在 finally 中无法修改。
3、当 return 返回的是引用数据类型时,在 finally 中可以修改。
- 点赞
- 收藏
- 关注作者
评论(0)