Java try-finally 和 try-catch 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2854910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:42:13  来源:igfitidea点击:

Difference between try-finally and try-catch

javatry-catchtry-finally

提问by Vijay Kotari

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?

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

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

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

采纳答案by tangens

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.
  • 只有在 try 块中抛出异常时才会执行 catch 块。
  • finally 块总是在 try(-catch) 块之后执行,无论是否抛出异常。

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.

而且,就像@codeca 在他的评论中所说的那样,无法访问 finally 块内的异常,因为即使没有异常,也会执行 finally 块。

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.

当然,您可以在块外声明一个保存异常的变量,并在 catch 块内分配一个值。之后,您可以在 finally 块中访问此变量。

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

回答by Kieran

try is used to run a method that may throw an exception

try 用于运行可能抛出异常的方法

catch is used to "catch" stop that exception

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

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

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
}

回答by Michiel Buddingh

These are not variations, they're fundamentally different things. finallyis executed always, catchonly when an exception occurs.

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

回答by mkorpela

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

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

回答by gmhk

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.
  1. 所有 try 语句必须包含一个 catch 子句或一个 finally 子句
  2. 它可以有多个 catch 子句但只有一个 finally 子句
  3. 在任何执行过程中,如果发生任何错误,则 Control 将转移到适当的 Catch 块并执行语句并执行 finally 块。

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.

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

回答by TheMorph

Finally and catch blocks are quite different:

finally 和 catch 块是完全不同的:

  • Within the catch block you can respond to the thrown exception. This block is executed only if there is an unhandled exceptionand the type matches the one or is subclass of the one specified in the catch block's parameter.
  • Finally will be always executedafter try and catch blocks whether there is an exception raised or not.
  • 在 catch 块中,您可以响应抛出的异常。仅当存在未处理的异常且类型与 catch 块的参数中指定的异常或类型相匹配时,才会执行此块。
  • 无论是否引发异常,最终都会在 try 和 catch 块之后执行


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

如果你定义了一个 try 块,你必须定义

  1. one finally block, or
  2. one or more catch blocks, or
  3. one or more catch blocks and one finally block
  1. 最后一个块,或
  2. 一个或多个 catch 块,或
  3. 一个或多个 catch 块和一个 finally 块

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
}

回答by fastcodejava

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.

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

回答by Hari krishna

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.

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

回答by Android Tutorial

Finally and catch blocks are quite different:

finally 和 catch 块是完全不同的:

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.

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

回答by Android Tutorial

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.

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

}

Maybe other guys like me searched for something like this.

也许其他像我这样的人搜索过这样的东西。

Information from this page tutpoint

来自此页面的信息tutpoint