【注意】最后更新于 May 22, 2019,文中内容可能已过时,请谨慎使用。
背景
在java编程过程中,经常会使用 try catch语句来处理异常,对打开了资源的文件的,要使用finally进行关闭。
正常的执行顺序是 try块,如果没有异常执行finally块,有异常跳转到catch块,最后执行finally块。 刚好遇到一个try catch 带有finally的语句,还使用了return。于是,就想到了语句执行情况的问题。
验证
编程,哪里不清楚,运行一下不就好了。交代一下运行环境,操作系统是 Windows7 64位,使用的java环境是java 1.8.0_66。
类的基本定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class TryCachTest {
// catch 工作
public static String catchMethod() {
System.out.println("catchMethod is running ==1==");
return "catch method";
}
// finally工作
public static String finallyMethod() {
System.out.println("finallyMethod is running ==2==");
return "finally method";
}
// return 工作
public static String returnMethod(String methodName){
System.out.println( methodName + " call returnMethod is running ==3==");
return "=" + methodName;
}
}
|
正常抛出异常,没有finally, try块、catch块均有return 执行情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static String catchTest() {
System.out.println("====catchTest=====");
try {
int i = 10 / 0; // 抛出 Exception,后续处理被拒绝
System.out.println("i vaule is : " + i);
return returnMethod("catchTest"); // Exception 已经抛出,没有获得被执行的机会
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod(); // Exception 抛出,获得了调用方法并返回方法值的机会
}
}
public static void main(String[] args) {
System.out.println(catchTest());
}
|
输出为
====catchTest=====
– Exception –
catchMethod is running ==1==
catch method
说明: 在try块中,遇到异常,异常之后的语句没有机会执行。try抛出异常后执行catch块内容
正常抛出异常,有finally,try块、catch块有return,finally无return 执行情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static String catchFinallyTest1() {
System.out.println("=========");
System.out.println("catchFinallyTest1");
try {
int i = 10 / 0; // 抛出 Exception,后续处理被拒绝
System.out.println("i vaule is : " + i); // Exception 已经抛出,没有获得被执行的机会
return returnMethod("catchFinallyTest1");
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod(); // Exception 抛出,获得了调用方法的机会,但方法值在 finally 执行完后才返回
} finally {
finallyMethod(); // Exception 抛出,finally 代码块将在 catch 执行 return 之前被执行
}
}
public static void main(String[] args) {
System.out.println(catchFinallyTest1());
}
|
输出为:
=========
catchFinallyTest1
– Exception –
catchMethod is running ==1==
finallyMethod is running ==2==
catch method
说明: 在try块中,遇到异常,异常之后的语句没有机会执行。try抛出异常后执行catch块内容,直到catch块执行到 return 语句之前(return关键字参数也会执行),跳转执行finally。等finally执行完后再返回 catch的return值。
不抛出异常,有finally,try块、catch块有return,finally无return 执行情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static String catchFinallyTest2() {
System.out.println("=========");
System.out.println("catchFinallyTest2");
try {
int i = 10 / 2; // 不抛出 Exception
System.out.println("i vaule is : " + i);
return returnMethod("catchFinallyTest2");
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod(); // 不抛出 Exception ,没有获得被执行的机会
} finally {
finallyMethod(); // 不抛出 Exception ,finally 代码块将在 try 执行 return 之前被执行
}
}
public static void main(String[] args) {
System.out.println(catchFinallyTest2());
}
|
输出为:
=========
catchFinallyTest2
i vaule is : 5
catchFinallyTest2 call returnMethod is running ==3==
finallyMethod is running ==2==
=catchFinallyTest2
说明: 在try块中,没有遇到异常,try块会执行到return之前(return关键字参数也会执行),跳转到finally执行,最后执行返回 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
30
31
32
33
34
|
public static String catchFinallyTest3() {
System.out.println("=========");
System.out.println("catchFinallyTest3");
try {
int i = 10 / 2; // 不抛出 Exception
System.out.println("i vaule is : " + i);
return returnMethod("catchFinallyTest3"); // 获得被执行的机会,但执行需要在 finally 执行完成之后才能被执行
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod();
} finally {
return finallyMethod(); // finally 中含有 return 语句,这个 return 将结束这个方法,不会在执行完之后再跳回 try 或 catch 继续执行,方法到此结束,返回 false
}
}
public static String catchFinallyTest4() {
System.out.println("=========");
System.out.println("catchFinallyTest4");
try {
int i = 10 / 0; // 抛出 Exception,后续处理被拒绝
System.out.println("i vaule is : " + i); // Exception 已经抛出,没有获得被执行的机会
return returnMethod("catchFinallyTest4");
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod();
} finally {
return finallyMethod(); // finally 中含有 return 语句,这个 return 将结束这个方法,不会在执行完之后再跳回 try 或 catch 继续执行,方法到此结束,返回 false
}
}
public static void main(String[] args) {
System.out.println(catchFinallyTest3());
System.out.println(catchFinallyTest4());
}
|
输出为:
=========
catchFinallyTest3
i vaule is : 5
catchFinallyTest3 call returnMethod is running ==3==
finallyMethod is running ==2==
finally method
catchFinallyTest4
– Exception –
catchMethod is running ==1==
finallyMethod is running ==2==
finally method
说明: 若try、catch、finally块中都包含有 return 关键字,最后返回的值是 finally 块中的值。该执行的 return 关键字参数语句会执行
若try或catch块中包含有exit()
方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static String catchFinallyTest5() {
System.out.println("=========");
System.out.println("catchFinallyTest5");
try {
int i = 10 / 2; // 不抛出 Exception
System.out.println("i vaule is : " + i);
System.exit(0);
} catch (Exception e) {
System.out.println(" -- Exception --");
return catchMethod();
} finally {
return finallyMethod(); // finally 中含有 return 语句,这个 return 将结束这个方法,不会在执行完之后再跳回 try 或 catch 继续执行,方法到此结束,返回 false
}
}
public static void main(String[] args) {
System.out.println(catchFinallyTest5());
}
|
输出为:
=========
catchFinallyTest5
i vaule is : 5
说明: 若try(catch)块下包含有exit()方法,执行到exit()方法时,程序直接退出,不会做其他的清理工作。
总结
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
32
33
34
35
36
37
38
39
40
41
|
st=>start: 开始
e=>end: 结束
op1=>operation: 进入Try代码块
op11=>operation: 执行到Try代码块的
Return前(包含Return参数)
op12=>operation: Return Try块的返回参数
op2=>operation: 进入Catch代码块并执行到
Return前(包含Return参数)
op21=>operation: Return Catch块的返回参数
op3=>operation: 进入Finally代码块并执行到
op30=>operation: 进入Finally代码块并执行到
Return前(包含Return参数)
op31=>operation: Return Finally块的返回参数
cond1=>condition: 是否抛
出异常
cond2=>condition: 是否包含
Finally块
cond3=>condition: Finally块是
否包含Return
cond21=>condition: 是否包含
Finally块
cond31=>condition: Finally块是
否包含Return
st->op1->cond1
cond1(yes)->op2->cond2
cond1(no)->op11->cond21
cond2(yes)->op3->cond3
cond3(yes)->op31
cond3(no)->op21
cond2(np)->op21
cond21(yes)->op30->cond31
cond21(no)->op12
cond31(yes)->op31
cond31(no)->op12
op12->e
op21->e
op31->e
|