zoukankan      html  css  js  c++  java
  • java finally

    一.使用finally进行清理

    对于一些代码,可能会希望无论try块中的异常是否被抛出,它们都能得到执行,这通常适用于内存回收之外的情况(内存回收由垃圾回收器完成),为了达到这个效果,可以异常处理程序后面加上finally子句,完整的异常处理程序看起来像这样:

    try{
       // The guarded region: dangerous activities
       // that might  throw A. B. or C
    } catch(A a1){
       // Handler for situation A
    } catch(B b1){
       //Handler for situation B
    } catch(C c1){
       // Handler for situation C
    } finally{
      //Activities that happen every time
    }

    为了证明finaly总会被执行,可以试试下面的程序

    package exceptions;
    //: exceptions/FinallyWorks.java
    // The finally clause is always executed.
    
    class ThreeException extends Exception {}
    
    public class FinallyWorks {
      static int count = 0;
      public static void main(String[] args) {
        while(true) {
          try {
            // Post-increment is zero first time:
            if(count++ == 0)
              throw new ThreeException();
            System.out.println("No exception");
          } catch(ThreeException e) {
            System.out.println("ThreeException");
          } finally {
            System.out.println("In finally clause");//在异常被抛出是执行了一次,在System.out.println(Noexception")后又执行了一次
            if(count == 2) break; // out of "while"
          }
        }
      }
    } /* Output:
    ThreeException
    In finally clause
    No exception
    In finally clause
    *///:~

    可以看到无论异常是否被抛出,finally子句总会被执行.这个程序也给了我们一些思路,当java中的异常不允许我们回到异常抛出的地点,那么如何应对呢? 如果把try块放在循环里,就建立了一个"程序继续执行之前必须要达到"的条件,还可以加入static类型的计数器或者别的装置,使循环在放弃以前能尝试一定的次数,这将使程序的健壮性更上一个台阶

    二. finally可以用来做什么

    1.) Java中使用finally一般把除内存之外的资源恢复到它们的初始状态时.这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上画的图形,甚至可以是外部世界的某个开关

    package exceptions;
    //: exceptions/Switch.java
    import static net.mindview.util.Print.*;
    
    public class Switch {
      private boolean state = false;
      public boolean read() { return state; }
      public void on() { state = true; print(this); }
      public void off() { state = false; print(this); }
      public String toString() { return state ? "on" : "off"; }
    } ///:~
    
     package exceptions;
    //: exceptions/OnOffException1.java
    public class OnOffException1 extends Exception {} ///:~
    package exceptions;
    //: exceptions/OnOffException2.java
    public class OnOffException2 extends Exception {} ///:~
    package exceptions;
    //: exceptions/OnOffSwitch.java
    // Why use finally?
    
    public class OnOffSwitch {
      private static Switch sw = new Switch();
      public static void f()
      throws OnOffException1,OnOffException2 {}
      public static void main(String[] args) {
        try {
          sw.on();
          // Code that can throw exceptions...
          f();
          sw.off();
        } catch(OnOffException1 e) {
          System.out.println("OnOffException1");
          sw.off();//异常未被捕获,sw.off没有执行
        } catch(OnOffException2 e) {
          System.out.println("OnOffException2");
          sw.off();
        }
      }
    } /* Output:
    on
    off
    *///:~

    程序的目的是确保main()结束时开关必须关闭,所以每个try块和异常处理程序的末尾都加入了对sw.off()方法的调用,但也可能异常被抛出,但没有被处理程序捕获,这是sw.off()就得不到调用,但有了finally,只要把try块中清理的代码移放到一起即可

    package exceptions;
    //: exceptions/WithFinally.java
    // Finally Guarantees cleanup.
    
    public class WithFinally {
      static Switch sw = new Switch();
      public static void main(String[] args) {
        try {
          sw.on();
          // Code that can throw exceptions...
          OnOffSwitch.f();
        } catch(OnOffException1 e) {
          System.out.println("OnOffException1");
        } catch(OnOffException2 e) {
          System.out.println("OnOffException2");
        } finally {
          sw.off();
        }
      }
    } /* Output:
    on
    off
    *///:~

    2. 异常处理机制会在跳到更高一层的异常处理程序之前,执行finall当涉及到break和continue语句时finally也会被执行

    package exceptions;
    //: exceptions/AlwaysFinally.java
    // Finally is always executed.
    import static net.mindview.util.Print.*;
    
    class FourException extends Exception {}
    
    public class AlwaysFinally {
      public static void main(String[] args) {
        print("Entering first try block");
        try {
          print("Entering second try block");
          try {
            throw new FourException();
          } finally {
            print("finally in 2nd try block");
          }
        } catch(FourException e) {
          System.out.println(
            "Caught FourException in 1st try block");
        } finally {
          System.out.println("finally in 1st try block");
        }
      }
    } /* Output:
    Entering first try block
    Entering second try block
    finally in 2nd try block
    Caught FourException in 1st try block
    finally in 1st try block
    *///:~

     三.在return中使用finally

    1.) 因为finally子句总是会执行,所以在一个方法中,可以从多个点返回,并且可以保证重要清理工作仍旧会执行.从输出可以看出在fianlly类内部,从何处返回无关紧要,return语句返回之前会执行finally子句的代码块.

    package exceptions;
    //: exceptions/MultipleReturns.java
    import static net.mindview.util.Print.*;
    
    public class MultipleReturns {
      public static void f(int i) {
        print("Initialization that requires cleanup");
        try {
          print("Point 1");
          if(i == 1) return;
          print("Point 2");
          if(i == 2) return;
          print("Point 3");
          if(i == 3) return;
          print("End");
          return;
        } finally {
          print("Performing cleanup");
        }
      }
      public static void main(String[] args) {
        for(int i = 1; i <= 4; i++)
          f(i);
      }
    } /* Output:
    Initialization that requires cleanup
    Point 1
    Performing cleanup
    Initialization that requires cleanup
    Point 1
    Point 2
    Performing cleanup
    Initialization that requires cleanup
    Point 1
    Point 2
    Point 3
    Performing cleanup
    Initialization that requires cleanup
    Point 1
    Point 2
    Point 3
    End
    Performing cleanup
    *///:~
  • 相关阅读:
    适用于 Laravel 的内部收单模块
    适用于 Laravel API 的签名看守器
    适用于 Laravel 的百度搜索推送
    适用于Yii2的千万级数据秒分页
    PostMan 代理的一个大坑
    PHP 各种金融利息的计算方法
    软件工程之UML建模课
    Windows 通过 cmd 得到域名的dns
    在windows下,通过git-bash里的ssh,远程登陆虚拟机里的linux
    Java常见缩写
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10298190.html
Copyright © 2011-2022 走看看