服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用finally做什么


  在没有“垃圾收集”以及“自动调用破坏器”机制的一种语言中(注释⑤),finally显得特别重要,因为程序员可用它担保内存的正确释放――无论在try块内部发生了什么状况。但java提供了垃圾收集机制,所以内存的释放几乎绝对不会成为问题。另外,它也没有构建器可供调用。既然如此,java里何时才会用到finally呢?
  
  ⑤:“破坏器”(destructor)是“构建器”(constructor)的反义词。它代表一个特殊的函数,一旦某个对象失去用处,通常就会调用它。我们肯定知道在哪里以及何时调用破坏器。c++提供了自动的破坏器调用机制,但delphi的object pascal版本1及2却不具备这一能力(在这种语言中,破坏器的含义与用法都发生了变化)。
  
  除将内存设回原始状态以外,若要设置另一些东西,finally就是必需的。例如,我们有时需要打开一个文件或者建立一个网络连接,或者在屏幕上画一些东西,甚至设置外部世界的一个开关,等等。如下例所示:
  
  //: onoffswitch.java
  // why use finally?
  
  class switch {
   boolean state = false;
   boolean read() { return state; }
   void on() { state = true; }
   void off() { state = false; }
  }
  
  public class onoffswitch {
   static switch sw = new switch();
   public static void main(string[] args) {
    try {
     sw.on();
     // code that can throw exceptions...
     sw.off();
    } catch(nullpointerexception e) {
     system.out.println("nullpointerexception");
     sw.off();
    } catch(illegalargumentexception e) {
     system.out.println("ioexception");
     sw.off();
    }
   }
  } ///:~
  
  这里的目标是保证main()完成时开关处于关闭状态,所以将sw.off()置于try块以及每个违例控制器的末尾。但产生的一个违例有可能不是在这里捕获的,这便会错过sw.off()。然而,利用finally,我们可以将来自try块的关闭代码只置于一个地方:
  
  //: withfinally.java
  // finally guarantees cleanup
  
  class switch2 {
   boolean state = false;
   boolean read() { return state; }
   void on() { state = true; }
   void off() { state = false; }
  }
  
  public class withfinally {
   static switch2 sw = new switch2();
   public static void main(string[] args) {
    try {
     sw.on();
     // code that can throw exceptions...
    } catch(nullpointerexception e) {
     system.out.println("nullpointerexception");
    } catch(illegalargumentexception e) {
     system.out.println("ioexception");
    } finally {
     sw.off();
    }
   }
  } ///:~
  
  在这儿,sw.off()已移至一个地方。无论发生什么事情,都肯定会运行它。
  即使违例不在当前的catch从句集里捕获,finally都会在违例控制机制转到更高级别搜索一个控制器之前得以执行。如下所示:
  
  //: alwaysfinally.java
  // finally is always executed
  
  class ex extends exception {}
  
  public class alwaysfinally {
   public static void main(string[] args) {
    system.out.println(
     "entering first try block");
    try {
     system.out.println(
      "entering second try block");
     try {
      throw new ex();
     } finally {
      system.out.println(
       "finally in 2nd try block");
     }
    } catch(ex e) {
     system.out.println(
      "caught ex in first try block");
    } finally {
     system.out.println(
      "finally in 1st try block");
    }
   }
  } ///:~
  
  该程序的输出展示了具体发生的事情:
  
  entering first try block
  entering second try block
  finally in 2nd try block
  caught ex in first try block
  finally in 1st try block
  
  若调用了break和continue语句,finally语句也会得以执行。请注意,与作上标签的break和continue一道,finally排除了java对goto跳转语句的需求。

扫描关注微信公众号