finally用法

来源:互联网 发布:中国期货数据 编辑:程序博客网 时间:2024/06/05 04:51

不管 try 语句块正常结束还是异常结束,finally 语句块是保证要执行的。如果 try 语句块正常结束,那么在 try 语句块中的语句都执行完之后,再执行 finally 语句块。

Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,免得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。请注意,前文中我们曾经提到过 return、throw 和 break、continue 的区别,对于这条规则(保留返回值),只适用于 return 和 throw 语句,不适用于 break 和 continue 语句,因为它们根本就没有返回值。

当finally里面也有return时
a finally clause is always entered with a reason. That reason may be that the try code finished normally, that it executed a control flow statement such as return, or that an exception was thrown in code executed in the Try block. The reason is remembered when the finally clause exits by falling out the bottom. However, if the finally block creates its own reason to leave by executing a control flow statement (such as break or return) or by throwing an exception, that reason supersedes the original one, and the original reason is forgotten. For example, consider the following code:
try {
// … do something …
return 1;
} finally {
return 2;
}
When the Try block executes its return, the finally block is entered with the “reason” of returning the value 1. However, inside the finally block the value 2 is returned, so the initial intention is forgotten. In fact, if any of the other code in the try block had thrown an exception, the result would still be to return 2. If the finally block did not return a value but simply fell out the bottom, the “return the value 1 ″ reason would be remembered and carried out.

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");          }      }  public static String test1() {  System.out.println("return statement");  return "after return";      }  }

结果为`

try block return statement finally block after return``理解的方法:  return test1(); 就相当于                        String temp=test1();                        return temp;finally语句块会在try或者catch的控制转移语句(return throw continue break  但是returnthrowcontinuebreak不一样   return,throw返回给调用者)之前执行

import java.io.*;
public class KK {
static int m()
{
int i=1;
try{
i=4;
return i;

    }finally{         //实际执行的是注释的  finally里面开得是一个临时变量        //int temp=i;        //temp++;        i++;    }}public static void main(String args[])throws Exception{  int i=m();    System.out.println(i);}

}

![这里写图片描述](https://www.ibm.com/developerworks/cn/java/j-lo-finally/image002.jpg)finally不紧用于处理异常  还用于资源的释放
import java.io.*;public class KK {    public static void main(String args[]){    FileInputStream f=null;    try{     f=new FileInputStream("aa.txt");    }catch(FileNotFoundException e){        e.printStackTrace();    }finally{        if(f!=null)        {            try{                f.close();            }catch(IOException e){                e.printStackTrace();            }        }    }    }}

没有 catch 语句,哪来的异常处理呢?我觉得这是一个好问题,其实,即使没有 catch 语句,Java 编译器编译出的字节码中还是有默认的异常处理的,别忘了,除了需要捕获的异常,还可能有不需捕获的异常(如:RunTimeException 和 Error)。

finally一定执行吗?
1.一定要是对应的try 被执行了 对应的finally才会执行
2. 在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行。则finally不会执行
3. 当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。还有更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。

参考:
https://www.ibm.com/developerworks/cn/java/j-lo-finally/