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

发布于 2024-09-02 02:52:07 字数 349 浏览 10 评论 0原文

有什么区别

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

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

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

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

What's the difference between

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

and

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

I like the second version better because it gives me access to the Throwable. Is there any logical difference or a preferred convention between the two variations?

Also, is there a way to access the exception from the finally clause?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

盛夏已如深秋| 2024-09-09 02:52:07

这是两个不同的事情:

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

These are two different things:

  • The catch block is only executed if an exception is thrown in the try block.
  • The finally block is executed always after the try(-catch) block, if an exception is thrown or not.

In your example you haven't shown the third possible construct:

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
}

And, like @codeca says in his comment, there is no way to access the exception inside the finally block, because the finally block is executed even if there is no exception.

Of course you could declare a variable that holds the exception outside of your block and assign a value inside the catch block. Afterwards you can access this variable inside your finally block.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
半窗疏影 2024-09-09 02:52:07

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

These are not variations, they're fundamentally different things. finally is executed always, catch only when an exception occurs.

小姐丶请自重 2024-09-09 02:52:07

finally 和 catch 块有很大不同:

  • 在 catch 块中,您可以响应抛出的异常。 仅当存在未处理的异常并且类型与 catch 块的参数中指定的类型匹配或者是该类型的子类时,才会执行此块。
  • 无论是否引发异常,Finally 始终会在 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
}

Finally and catch blocks are quite different:

  • Within the catch block you can respond to the thrown exception. This block is executed only if there is an unhandled exception and the type matches the one or is subclass of the one specified in the catch block's parameter.
  • Finally will be always executed after try and catch blocks whether there is an exception raised or not.

So

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
}

differs from

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

significantly.

If you define a try block you have to define

  1. one finally block, or
  2. one or more catch blocks, or
  3. one or more catch blocks and one finally block

So the following code would be valid too:

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
}
橪书 2024-09-09 02:52:07

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 is used to run a method that may throw an exception

catch is used to "catch" stop that exception

finally is used for any clean up needed from that exception being caught or not

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
}
花海 2024-09-09 02:52:07
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块被执行。

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

try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. All try statements must include either one catch clause or a finally clause
  2. It can have a multiple catch clauses but only one finally clause
  3. During any execution, if any errors occurs, then the Control is transferred to the appropriate Catch block and executes the statements and Finally block is executed.

No Matter what The Finally block is always executed, So in General, Finally block is used, when you have sessions, Database connections or Files or sockets are open, then the code for closing those connections will be placed.
This is just to make sure in an application no memory leaks or Any other issues should not occur.

七颜 2024-09-09 02:52:07

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

In My reasearch Finally block is always executed and it is mainly "used for the any open connections to close" and to destroy something that is running unnecessarily.

十年九夏 2024-09-09 02:52:07

finally 和 catch 块有很大不同:

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

Finally and catch blocks are quite different:

Within the catch block you can respond to the thrown exception. This block is executed only if there is an unhandled exception and the type matches the one or is subclass of the one specified in the catch block's parameter.
Finally will be always executed after try and catch blocks whether there is an exception raised or not.

夕嗳→ 2024-09-09 02:52:07

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

Generally when we use any resources like streams, connections etc.. we have to close them explicitly using finally block. In the program given below we are reading data from a file using FileReader and we are closing it using finally block.

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();
           }
       }
    }

}

Maybe other guys like me searched for something like this.

Information from this page tutpoint

帅哥哥的热头脑 2024-09-09 02:52:07

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

Finally block is always executed. Catch block is executed only when an exception that matches the blocks parameter is catched.

自此以后,行同陌路 2024-09-09 02:52:07

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

Even in the first form you could log it in the calling method. So there is no big advantage unless you want to do some special handling right there.

愿得七秒忆 2024-09-09 02:52:07

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

Try block will hold the statements which are going to raise exception.
The catch block will hold the reference thrown from the try block and required messages are generated from catch block.
Finally block is also used to close the used resources like io closing,file closing, dB closing..
In Java -9 enhanced try-with resource came up where the resources are declared outside the try..in enchanced try with resource the catch block is mandatory

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文