finally的使用

来源:互联网 发布:人工智能与智能控制 编辑:程序博客网 时间:2024/05/03 15:05

    finally一般是在try..catch语句最后用来释放资源等操作的,在一般人的印象中finally{}中的语句是一定会执行的,其实不然。.如果程序在进入try...catch语句之前产生异常,从而没有进入try...catch语句,那么对应于该try..catch的finally语句并不会执行。

对于try..catch语句中有控制转移语句(return、break、continue)的情况:

package Test;public class FinallyTest{public static void main(String[] args){try{System.out.println("try block");return;}finally{System.out.println("finally block");return;}}}
打印结果为:
try block
finally block
上面程序的答应结果说明:finally中的语句是在try中的流程转移语句之前执行的。


再来看看下面的程序,就会有疑惑了。

package Test;public class FinallyTest {  public static void main(String[] args) {         System.out.println("return value of getValue(): " + getValue()); }  public static String getValue() {        String result = "try";        try {                  return result;         } finally {                 result = result + " finally";        }  }  } 
按道理来说,打印的结果应该是“try finally”,但是打印出来的结果让人大跌眼镜“try”,这是为什么呢?

下面一段话是摘抄的:

“关于 Java 虚拟机是如何编译 finally 语句块的问题,有兴趣的读者可以参考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 节 Compiling finally。那里详细介绍了 Java 虚拟机是如何编译 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 语句,因为它们根本就没有返回值。”



原创粉丝点击