Java中关于try…catch…finally异常处理的细节辨析
什么时候执行finally; finally后面的语句执行吗; try…catch…finally块中的finally语句是不是一定会被执行; Java中finally与return的执行顺序详解;
首先需要明确几点:
- try语句块中的代码应是可能出现异常的代码,可能会抛出一个或多个异常,因此,try后面可跟一个或多个catch
- 如果异常间关系不大,则catch的顺序可以随意。但如果异常间有父类子类继承关系,则必须将子类异常catch放置在父类异常catch前面,以防止一场直接被父类catch接住,没有输出我们想要的具体子类异常信息
- 如果try中没有出现异常,则catch不被执行。但不管catch接没接住,try有没有异常,只要有finally,则都会执行finally(general情况,其他情况详见后)。
- finally后面的语句是否执行与try或catch中有无return有关
这篇博客耗的时间比较长,我仔细验证了几个猜测。现在记录下来。
整篇文章较长,阅读大约需要8min
finally后面的语句什么时候执行?
还是先看一个例子:
public class TestFinally {
public static void main(String[] args){
try{
return;
}
finally{
System.out.println("Finally");
}
}
}
输出:
Finally
可以看出:当try中无异常发生,finally仍执行
如果去除return更换为其它普通语句
public class TestFinally {
public static void main(String[] args){
try{
int a=3;
a+=5;
System.out.println(a);
}
finally{
System.out.println("Finally");
}
int b=5;
b+=5;
System.out.println(b);
}
}
输出:
8
Finally
10
可以看出:finally后面语句正常执行
如果try中加入return
,不能编译,提示
int b=5;
b+=5;
System.out.println(b);
这部分代码是unreachable code
得证如果try中有return,则finally后面的代码不会执行(for ‘catch’ is the same thing)
附上一些证明栗子,可以跳过
例1
public class TestFinally {
public static void a() throws Exception{
try{
throw new Exception();
}
catch(Exception e){
System.out.println("exception000");
}
finally{
System.out.println("finally111");
}
}
public static void main(String[] args){
try{
a();
}
catch(Exception e){
System.out.println("exception");
}
System.out.println("finished");
}
}
输出:
exception000
finally111
finished
异常在方法中被接住,main中catch不会执行,catch后的代码正常执行
删去exception000项后
public class TestFinally {
public static void a() throws Exception{
try{
throw new Exception();
}
/*catch(Exception e){
System.out.println("exception000");
}*/
finally{
System.out.println("finally111");
}
}
public static void main(String[] args){
try{
a();
}
catch(Exception e){
System.out.println("exception");
}
System.out.println("finished");
}
}
输出:
finally111
exceptio