try-finally和try-catch之间的区别

时间:2010-05-18 06:15:14

标签: java try-catch try-finally

之间有什么区别
try {
    fooBar();
} finally {
    barFoo();
}

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

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

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

11 个答案:

答案 0 :(得分:112)

这是两件不同的事情:

  • 只有在try块中抛出异常时才会执行catch块。
  • 如果抛出异常,则始终在try(-catch)块之后执行finally块。

在你的例子中,你没有展示第三种可能的结构:

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
    }
}

答案 1 :(得分:11)

这些不是变化,它们是根本不同的东西。只有在发生异常时,finally才会执行始终catch

答案 2 :(得分:7)

最后,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
}

显著。

如果您定义了试块,则必须定义

  1. 一个最终阻止,或
  2. 一个或多个catch块,或
  3. 一个或多个catch块,一个最终阻止
  4. 所以以下代码也是有效的:

    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
    }
    

答案 3 :(得分:4)

try用于运行可能引发异常的方法

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

最终用于任何被捕获的异常所需的清理

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
}

答案 4 :(得分:4)

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. 在任何执行期间,如果发生任何错误,则将控制转移到相应的Catch块并执行语句并执行Finally块。
  4. 无论什么,总是执行Finally块,所以在General中,使用Finally块,当你有会话,数据库连接或文件或套接字打开时,将放置关闭这些连接的代码。 这只是为了确保在应用程序中没有内存泄漏或任何其他问题不应该发生。

答案 5 :(得分:4)

最后,catch块非常不同:

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

答案 6 :(得分:3)

在我的研究中,最终块始终被执行,它主要用于任何打开的连接以关闭"并摧毁一些不必要的东西。

答案 7 :(得分:2)

最后总是执行块。仅当捕获与blocks参数匹配的异常时才执行Catch块。

答案 8 :(得分:2)

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

答案 9 :(得分:2)

通常当我们使用任何资源(如流,连接等)时,我们必须使用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

答案 10 :(得分:0)

Try块将保存将引发异常的语句。 catch块将保存从try块抛出的引用,并从catch块生成所需的消息。 最后,块还用于关闭已使用的资源,例如io关闭,文件关闭,dB关闭。 在Java -9中,出现了增强的try-with资源,其中在try ..之外声明了资源。.在增强了try的资源中,catch块是必需的