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

有什么区别

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

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

我更喜欢第二个版本,因为它使我能够访问Throwable。 这两个变体之间是否有任何逻辑差异或者优先约定?

另外,有没有办法从finally子句中访问exception呢?

这是两件不同的事情:

  • catch块只有在try块中抛出一个exception时才被执行。
  • 如果抛出exception,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块中没有办法访问exception,因为即使没有exception,finally块也会被执行。

当然,你可以声明一个variables来保存块外的exception,并在catch块内赋值。 之后你可以在你的finally块中访问这个variables。

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

这些不是变化,它们是根本不同的东西。 finally 总是执行,只有在发生exception时才catch

最后和catch块是完全不同的:

  • 在catch块中,您可以响应抛出的exception。 只有在存在未处理的exception并且types匹配catch块的参数中指定的types或子类时, 才会执行该块。
  • 最后总会在try和catch块之后执行 ,是否有exception引发。

所以

 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. 一个或多个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 } 
 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块。

不pipe什么总是执行Finally块,所以一般情况下,使用Finally块,当你有会话时,数据库连接或文件或套接字打开,那么closures这些连接的代码将被放置。 这只是为了确保在应用程序中没有内存泄漏或任何其他问题不应该发生。

最后和catch块是完全不同的:

在catch块中,您可以响应抛出的exception。 只有在存在未处理的exception并且types匹配catch块的参数中指定的types或子类时,才会执行该块。 最后总会在try和catch块之后执行,是否有exception引发。

尝试用于运行可能会引发exception的方法

catch是用来“catch”停止这个exception

最后是用来从那个exception被捕获或不需要的任何清理

 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 } 

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

最后块总是执行。 捕获块只有在捕获到与blocks参数匹配的exception时才会执行。

即使在第一种forms中,您也可以将其logging在调用方法中。 所以没有什么大的优势,除非你想在那里做一些特殊的处理。

通常当我们使用像stream,连接等任何资源时,我们必须使用finally块来明确地closures它们。 在下面给出的程序中,我们使用FileReader从文件中读取数据,并使用finally块closures它。

 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