最终尝试和尝试捕获之间的区别


90

之间有什么区别

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

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

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

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

Answers:


121

这是两件事:

  • 仅在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
    }
}

11
一个推论是,你不能访问Throwablefinally块,因为可能不存在一个Throwable
迪恩·哈丁


7

最后和catch块完全不同:

  • 在catch块中,您可以响应引发的异常。仅当存在未处理的异常并且类型与catch块的参数中指定的一个匹配或属于该捕获的子类时,才执行此块。
  • 无论是否引发异常,在try和catch块之后,final将始终执行

所以

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. 最后一块,或
  2. 一个或多个捕获块,或
  3. 一个或多个捕获块,最后一个块

因此,以下代码也将有效:

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
}

3
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块并执行语句,然后执行Final块。

总是执行Final块无关紧要,因此,一般来说,使用Final块,当您有会话,数据库连接或文件或套接字打开时,将放置用于关闭这些连接的代码。这仅仅是为了确保在应用程序中没有内存泄漏或其他任何问题都不会发生。


3

最后和catch块完全不同:

在catch块中,您可以响应引发的异常。仅当存在未处理的异常并且类型与catch块的参数中指定的一个匹配或属于该捕获的子类时,才执行此块。不管是否引发异常,在try和catch块之后,final将始终执行。


2

在My reasearch中,总是执行块,它主要是“用于关闭任何打开的连接”并破坏不必要的运行。


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的信息


1

最后,块始终执行。仅当捕获到与blocks参数匹配的异常时,才执行catch块。


1

即使采用第一种形式,您也可以将其记录在调用方法中。因此,除非您想在那里进行一些特殊处理,否则没有什么大的优势。


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.