Java中try...catch...finally语句中含有return语句的执行情况

首先看几个示例。

示例一(try中有return,finally中没有return):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main.java.com.study.tryCatchFinally;

/**
* @author: whb
* @description: try中有return,finally中没有return
*/
public class DemoOne {

public static void main(String[] args) {
System.out.println(test());
}

private static int test() {
int num = 10;
try {
System.out.println("try...");
return num += 100;
} catch (Exception e) {
System.out.println("catch...");
} finally {
if (num > 50) {
System.out.println("num > 50 : " + num);
}
System.out.println("finally...");
}
return num;
}
}

输出结果:

1
2
3
4
try...
num > 50 : 110
finally...
110

分析:

显然“return num += 100”被拆分成了“num = num+100”和“return num”两个语句,线执行try中的“num = num+100”语句,将其保存起来,在try中的”return num“执行前,先将finally中的语句执行完,而后再将110返回。

示例二(try和finally中均有return):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main.java.com.study.tryCatchFinally;

/**
* @author: whb
* @description: try和finally中均有return
*/
public class DemoTwo {

public static void main(String[] args) {
System.out.println(testTwo());
}

private static int testTwo() {
int num = 10;
try {
System.out.println("try...");
return num += 100;
} catch (Exception e) {
System.out.println("catch error...");
} finally {
if (num > 50) {
System.out.println("num > 50 : " + num);
}
System.out.println("finally...");
num = 100;
return num;
}
}
}

输出结果:

1
2
3
4
try...
num > 50 : 110
finally...
100

分析:

try中的return语句同样被拆分了,finally中的return语句先于try中的return语句执行,因而try中的return被”覆盖“掉了,不再执行。

示例三(finally中改变返回值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
25
26
27
28
29
package main.java.com.study.tryCatchFinally;

/**
* @author: whb
* @description: finally中改变返回值num
*/
public class DemoThree {

public static void main(String[] args) {
System.out.println(testThree());
}

private static int testThree() {
int num = 10;
try {
System.out.println("try...");
return num;
} catch (Exception e) {
System.out.println("catch error...");
} finally {
if (num > 20) {
System.out.println("num > 20 : " + num);
}
System.out.println("finally");
num = 100;
}
return num;
}
}

输出结果:

1
2
3
try...
finally
10

分析:

虽然在finally中改变了返回值num,但因为finally中没有return该num的值,因此在执行完finally中的语句后,testThree()函数会得到try中返回的num的值,而try中的num的值依然是程序进入finally代码块前保留下来的值,因此得到的返回值为10。

示例四(将num的值包装在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
25
26
27
28
29
30
31
package main.java.com.study.tryCatchFinally;

/**
* @author: whb
* @description: 将num的值包装在Num类中
*/
public class DemoFour {
public static void main(String[] args) {
System.out.println(test().num);
}

private static Num test() {
Num number = new Num();
try {
System.out.println("try");
return number;
} catch (Exception e) {
System.out.println("error");
} finally {
if (number.num > 20) {
System.out.println("number.num > 20 : " + number.num);
}
System.out.println("finally");
number.num = 100;
}
return number;
}
}
class Num {
public int num = 10;
}

输出结果:

1
2
3
try
finally
100

分析:

从结果中可以看出,同样是在finally中改变了返回值num的值,在示例三中,并没有被try中的return返回(test()方法得到的不是100),但在这里却被try中的return语句返回了。

对于含有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中的return语句返回的就是在finally中改变后的该属性的值。

本文标题:Java中try...catch...finally语句中含有return语句的执行情况

文章作者:王洪博

发布时间:2018年09月03日 - 10:09

最后更新:2019年09月12日 - 02:09

原始链接:http://whb1990.github.io/posts/65251ffc.html

▄︻┻═┳一如果你喜欢这篇文章,请点击下方"打赏"按钮请我喝杯 ☕
0%