简体   繁体   English

try-finally 和 try-catch 的区别

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

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.我更喜欢第二个版本,因为它让我可以访问 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?另外,有没有办法从 finally 子句中访问异常?

These are two different things:这是两件不同的事情:

  • The catch block is only executed if an exception is thrown in the try block.只有在 try 块中抛出异常时才会执行 catch 块。
  • The finally block is executed always after the try(-catch) block, if an exception is thrown or not. 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.当然,您可以在块外声明一个保存异常的变量,并在 catch 块内分配一个值。 Afterwards you can access this variable inside your finally block.之后,您可以在 finally 块中访问此变量。

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

These are not variations, they're fundamentally different things.这些不是变化,它们是根本不同的东西。 finally is executed always , catch only when an exception occurs. finally始终执行,仅在发生异常时catch

Finally and catch blocks are quite different: finally 和 catch 块是完全不同的:

  • Within the catch block you can respond to the thrown exception.在 catch 块中,您可以响应抛出的异常。 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.仅当存在未处理的异常并且类型与 catch 块的参数中指定的异常或类型相匹配时,才会执行此块。
  • Finally will be always executed after try and catch blocks whether there is an exception raised or not.无论是否引发异常,最终都会在 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一个或多个 catch 块,或
  3. one or more catch blocks and one finally block一个或多个 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
}

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
}
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所有 try 语句必须包含一个 catch 子句或一个 finally 子句
  2. It can have a multiple catch clauses but only one finally clause它可以有多个 catch 子句但只有一个 finally 子句
  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.在任何执行过程中,如果发生任何错误,则 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.不管是什么,Finally 块总是被执行,所以一般情况下,Finally 块被使用,当你有会话、数据库连接或文件或套接字打开时,就会放置关闭这些连接的代码。 This is just to make sure in an application no memory leaks or Any other issues should not occur.这只是为了确保在应用程序中没有内存泄漏或不应发生任何其他问题。

Finally and catch blocks are quite different: finally 和 catch 块是完全不同的:

Within the catch block you can respond to the thrown exception.在 catch 块中,您可以响应抛出的异常。 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.仅当存在未处理的异常且类型与 catch 块的参数中指定的异常或类型相匹配时,才会执行此块。 Finally will be always executed after try and catch blocks whether there is an exception raised or not.无论是否引发异常,最终都会在 try 和 catch 块之后执行。

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

Generally when we use any resources like streams, connections etc.. we have to close them explicitly using finally block.通常,当我们使用流、连接等任何资源时,我们必须使用 finally 块显式关闭它们。 In the program given below we are reading data from a file using FileReader and we are closing it using finally block.在下面给出的程序中,我们使用 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

Finally block is always executed.最后块总是被执行。 Catch block is executed only when an exception that matches the blocks parameter is catched.只有在捕获到与 blocks 参数匹配的异常时才会执行 catch block。

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.所以除非你想在那里做一些特殊的处理,否则没有什么大的优势。

Try block will hold the statements which are going to raise exception. Try 块将保存将引发异常的语句。 The catch block will hold the reference thrown from the try block and required messages are generated from catch block. catch 块将保存从 try 块抛出的引用,并从 catch 块生成所需的消息。 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 finally 块还用于关闭使用的资源,如 io 关闭、文件关闭、dB 关闭。在 Java -9 中,增强的 try-with 资源出现在 try 之外声明资源的地方。是强制性的

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

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