繁体   English   中英

try-finally 和 try-catch 的区别

[英]Difference between try-finally and try-catch

有什么区别

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

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

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

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

这是两件不同的事情:

  • 只有在 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始终执行,仅在发生异常时catch

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. 最后一个块,或
  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用于运行可能抛出异常的方法

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
}
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 块被使用,当你有会话、数据库连接或文件或套接字打开时,就会放置关闭这些连接的代码。 这只是为了确保在应用程序中没有内存泄漏或不应发生任何其他问题。

finally 和 catch 块是完全不同的:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM