java异常处理try、catch、finally及finally执行顺序详解



java异常处理try、catch、finally及finally执行顺序详解。

为什么要使用finally语句:
来看一下没有finally的异常处理try-catch语句:
count为要使用的资源,用完该资源后要释放该资源。那么可把释放资源的语句放到try-catch后执行,当前的程序不管是在执行完try语句块还是catch语句块,都将顺序执行到下面释放资源的语句。
int count = 0;  //初始化资源
try{
count++;
if(count == 1) throw new Exception(“Exception in try”);
}catch(Exception e){
System.out.println(“catch block”);
}
count = 0; //释放资源

然而假如在try或catch中有多条return语句,那在每条return语句之前,就都需先执行释放资源的语句:
public void f() throws Exception {
int count = 0;  //初始化资源
try{
doSomething;
statementMayCauseException;  //可能会抛出异常的语句,若异常没有被catch,则直接抛出,也不会执行到try-catch下面的语句
doSomething;
if(count == 1) throw new Exception1(“E1 in try”);
if(count == 2) throw new Exception2(“E2 in try”);
}catch(Exception1 e){
count = 0; //释放资源
throw e;  //再次把异常抛出,让上一级捕获。此时将不会执行catch外的语句,所以要先释放资源
}catch(Exception2 e){
count = 0; //释放资源
return; //返回了,也不会执行catch外的语句,所以要先释放资源
}
count = 0; //释放资源
}
这就需在每一个可能返回的地方及可能出现异常而导致程序跳转的地方,考虑如何释放资源,这样就会导致复杂和冗余。

因此需要finally语句。
把资源释放或状态还原的代码放到finally块中,可以保证在try和catch语句执行完后,一定会执行finally语句块,而不用考虑各种复杂的跳转情况。
int count = 0;
try{
count++;
if(count == 1)throw new Exception();
}catch(Exception e){
}finally{
count = 0;
}

2.java异常处理中finally什么时候执行
finally在return语句之后,跳转到上一级程序之前执行。
public class Test {
public static void main(String[] args) {
System.out .println(test ());
}
public static String test() {
try {
System.out .println(“try block”);
return test1 ();
} finally {
System.out .println(“finally block”);
//return ”finally”;
}
}
public static String test1() {
System.out .println(“return statement”);
return ”after return”;
}
}
结果:
try block
return statement
finally block
after return

程序实例源码分析:
1.try语句块,return test1(),则调用test1方法
2.test1()执行后返回”after return”,返回值”after return”保存在一个临时区域里
3.执行finally语句块。若finally语句有返回值,则此返回值将替换掉临时区域的返回值
4.将临时区域的返回值送到上一级方法中。

测试是正确的:如果若finally语句有返回值,则此返回值将替换掉临时区域的返回值

参考:
《thinking in Java》

http://blog.csdn.net/mymyway/article/details/7954549


2,验证finally真正执行顺序

package lee;
import java.io.*;
public class Test1{
public static void main(String argv[]){
Test1 m=new Test1();
System.out.println(m.amethod());
}
public int amethod(){
try{
FileInputStream dis =new FileInputStream(“Hello.txt”); //1,抛出异常
}catch ( Exception ex) {
System.out.println(“No such file found”);   //2.catch捕获异常,并执行
return -1;                                  //4,return 返回
}finally{
System.out.println(“Doing finally”);  //3.finally一定会执行,在return之前。(准确说,应该是return ;语句)

}
return 0;
}
}

输出结果为:

No such file found
Doing finally
-1

总结:finally其实是仅在return ; 语句执行前执行,如果return 一个函数,那么会先执行函数,但如果函数内有(return ;)语句,那么finally就会在这个(return ;)语句前执行。

ps:如果catch块有异常向外抛出,执行顺序呢:我执行说,你抛你得异常,我finally我的语句,我俩互不干涉,你别管我啥时执行,但我一定会执行的亲。 = =

关于finally,此时,您只需记着一点:除非调用system.exit()让程序退出或断电等因素致使程序中止,否则,无论任何因素,finally块都一定会执行!!