【问题标题】:Difference between try-finally and try-catchtry-finally 和 try-catch 的区别
【发布时间】:2011-02-20 17:54:09
【问题描述】:

有什么区别

try {
    fooBar();
} finally {
    barFoo();
}

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

我更喜欢第二个版本,因为它让我可以访问 Throwable。这两种变体之间是否存在逻辑差异或首选约定?

另外,有没有办法从 finally 子句访问异常?

【问题讨论】:

    标签: java try-catch try-finally


    【解决方案1】:

    这是两个不同的东西:

    • 只有在 try 块中抛出异常时才会执行 catch 块。
    • finally 块总是在 try(-catch) 块之后执行,无论是否抛出异常。

    在您的示例中,您没有展示第三种可能的构造:

    try {
        // try to execute this statements...
    }
    catch( SpecificException e ) {
        // if a specific exception was thrown, handle it here
    }
    // ... more catches for specific exceptions can come here
    catch( Exception e ) {
        // if a more general exception was thrown, handle it here
    }
    finally {
        // here you can clean things up afterwards
    }
    

    而且,就像@codeca 在他的评论中所说,没有办法访问 finally 块内的异常,因为即使没有异常,也会执行 finally 块。

    当然,您可以在块外声明一个保存异常的变量,并在 catch 块内分配一个值。之后,您可以在 finally 块中访问此变量。

    Throwable throwable = null;
    try {
        // do some stuff
    }
    catch( Throwable e ) {
        throwable = e;
    }
    finally {
        if( throwable != null ) {
            // handle it
        }
    }
    

    【讨论】:

    • 一个推论是你不能finally块访问Throwable,因为可能没有 Throwable.
    【解决方案2】:

    这些不是变体,它们是根本不同的东西。 finally总是执行,catch 仅在发生异常时执行。

    【讨论】:

      【解决方案3】:

      Finally 和 catch 块完全不同:

      • 在 catch 块中,您可以响应抛出的异常。此块仅在存在未处理的异常并且类型与 catch 块参数中指定的类型匹配或者是子类时才会执行。
      • 无论是否引发异常,都会在 try 和 catch 块之后始终执行

      所以

      try {
        //some code
      }
      catch (ExceptionA) {
        // Only gets executed if ExceptionA 
        // was thrown in try block
      }
      catch (ExceptionB) {
        // Only executed if ExceptionB was thrown in try 
        // and not handled by first catch block
      }
      

      不同于

      try {
        //some code
      }
      finally {
        // Gets executed whether or not 
        // an exception was thrown in try block
      }
      

      显着。

      如果你定义了一个 try 块,你必须定义

      1. 一个 finally 块,或者
      2. 一个或多个 catch 块,或
      3. 一个或多个 catch 块和一个 finally 块

      所以下面的代码也是有效的:

      try {
        //some code
      }
      catch (ExceptionA) {
        // Only gets executed if 
        // ExceptionA was thrown in try block
      }
      catch (ExceptionB) {
        // Only executed if ExceptionB was thrown in 
        // try and not handled by first catch block
      }
      //even more catch blocks
      finally {
        // Gets executed whether or not an 
        // exception was thrown in try block
      }
      

      【讨论】:

        【解决方案4】:

        try用于运行可能抛出异常的方法

        catch 用于“捕获”停止该异常

        finally 用于对是否捕获到该异常进行所需的任何清理

        try{
            myObject.riskyMethod(); // run a method that may throw an exception
        }
        catch(Exception ex){
            myLogger.log(ex.Message); // "catch" stop that exception
        }
        finally{
            myObject = null; // clean up needed from that exception being caught
        }
        

        【讨论】:

          【解决方案5】:
          try {
              statements;
          } catch (exceptionType1 e1) {      // one or multiple
              statements;                 
          } catch (exceptionType2 e2) {
              statements;
          }    
          ...
          } finally {                                 // one or none
              statements;
          }
          
          1. 所有 try 语句必须包含一个 catch 子句或一个 finally 子句
          2. 可以有多个catch子句但只有一个finally子句
          3. 在任何执行过程中,如果发生任何错误,则将 Control 转移到相应的 Catch 块并执行语句并执行 finally 块。

          无论如何,Finally 块总是被执行,所以一般来说,Finally 块被使用,当你有会话、数据库连接或文件或套接字打开时,将放置关闭这些连接的代码。 这只是为了确保在应用程序中不会发生内存泄漏或任何其他问题。

          【讨论】:

            【解决方案6】:

            Finally 和 catch 块完全不同:

            在 catch 块中,您可以响应抛出的异常。仅当存在未处理的异常并且类型与 catch 块参数中指定的类型匹配或者是子类时,才会执行此块。 finally 将始终在 try 和 catch 块之后执行,无论是否引发异常。

            【讨论】:

              【解决方案7】:

              在我的研究中,Finally 块总是被执行,它主要是“用于关闭任何打开的连接”并销毁不必要地运行的东西。

              【讨论】:

                【解决方案8】:

                通常当我们使用流、连接等任何资源时,我们必须使用 finally 块显式关闭它们。在下面给出的程序中,我们使用 FileReader 从文件中读取数据,并使用 finally 块关闭它。

                import java.io.File;
                import java.io.FileReader;
                import java.io.IOException;
                
                public class ReadData_Demo {
                
                   public static void main(String args[]){
                      FileReader fr=null;       
                      try{
                         File file=new File("file.txt");
                         fr = new FileReader(file);  char [] a = new char[50];
                         fr.read(a); // reads the content to the array
                         for(char c : a)
                         System.out.print(c); //prints the characters one by one
                      }catch(IOException e){
                          e.printStackTrace();
                       }
                       finally{ 
                          try{
                              fr.close();
                          }catch(IOException ex){       
                               ex.printStackTrace();
                           }
                       }
                    }
                
                }
                

                也许像我这样的其他人也搜索过类似的东西。

                来自此页面的信息tutpoint

                【讨论】:

                  【解决方案9】:

                  最终块总是被执行。只有在捕获到与 blocks 参数匹配的异常时才会执行 catch 块。

                  【讨论】:

                    【解决方案10】:

                    即使是第一种形式,您也可以在调用方法中记录它。所以除非你想在那里做一些特殊的处理,否则没有太大的优势。

                    【讨论】:

                      【解决方案11】:

                      Try 块将保存将引发异常的语句。 catch 块将保存从 try 块抛出的引用,并从 catch 块生成所需的消息。 finally 块也用于关闭已使用的资源,如 io 关闭、文件关闭、dB 关闭.. 在 Java -9 增强的 try-with 资源中,资源在 try..in 增强的 try-with 资源之外声明,catch 块是强制性的

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2013-11-09
                        • 2014-11-27
                        • 1970-01-01
                        • 2010-12-14
                        • 2019-02-28
                        • 2011-10-26
                        • 2014-04-14
                        • 1970-01-01
                        相关资源
                        最近更新 更多