return和finally谁先执行
# 10.return和finally谁先执行
本文聊聊try或catch块中,如果有了return,那么是return先执行还是finally先呢?
# 分类讨论
假设try块中有return语句,try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句。分为以下情况:
情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。
情况二:如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。
情况三:如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:
- 1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
- 2)如果return的数据是引用数据类型,而在finally中对该引用的成员变量的改变起作用,因为返回的是引用,引用是没有变的,但引用里面的成员变量被改变了
特殊情况:在try里面有
System.exit(0)
这样的语句,System.exit(0)
是终止Java虚拟机JVM的,连JVM都停止了,一切都结束了,也就不存在返回值给调用者的情况
# 情况一
finally中有return语句,会将try中的return语句”覆盖“。测试代码:
/* 情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,
直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。
*/
public static int testCase1(){
int number = 100;
try{
System.out.println("testCase1 try语句块执行中... ");
number += 100;
return number;
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("testCase1 finally语句块执行中...");
number = 500;
return number;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
执行结果:
System.out.println("testCase1返回:" + testCase1()); //500
# 情况二
如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句。测试代码:
/**
* 情况二:如果finally中没有return语句,也没有改变要返回值,
* 则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。
* @return
*/
public static int testCase2(){
int number = 100;
try{
System.out.println("testCase2 try语句块执行中... ");
number += 100;
return number;
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("testCase2 finally语句块执行中...");
}
return 10;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
执行结果:
System.out.println("testCase2返回:" + testCase2()); //200
# 情况三
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:
- 1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
- 2)如果return的数据是引用数据类型,而在finally中对该引用的成员变量的改变起作用,因为返回的是引用,引用是没有变的,但引用里面的成员变量被改变了
# 3.1
/**
* 情况三:如果finally中没有return语句,但是改变了要返回的值,并且返回的是基本数据类型,则改变不会生效
* @return
*/
public static int testCase3(){
int number = 100;
try{
System.out.println("testCase3 try语句块执行中... ");
number += 100;
return number;
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("testCase3 finally语句块执行中...");
number = 500;
}
return 10;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
运行结果:
System.out.println("testCase3返回:" + testCase3()); //200
# 3.2
/**
* 情况三:如果finally中没有return语句,但是改变了要返回的值,并且返回的是引用数据类型,则改变会生效
* @return
*/
public static Num testCase3_2(){
Num number = new Num();
try{
System.out.println("testCase3_2 try语句块执行中... ");
return number;
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("testCase3_2 finally语句块执行中...");
number.num = 100;
}
return number;
}
class Num{
public int num = 1;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
运行结果:
System.out.println("testCase3_2返回:" + testCase3_2().num); //200
# 总结
即使在try或catch代码块中有return语句,也会执行finally语句,但是finally能否改变返回的值,取决于return后的内容是否为引用类型,如果是则引用的成员变量可以发生改变,如果为基本数据类型,则不可发生改变。
参考:
return和finally谁先执行_先return还是先finally_醺泽的博客-CSDN博客 (opens new window)
try catch 语句中有return 的各类情况_hello_world_he的博客-CSDN博客 (opens new window)