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

Vij*_*ari 82 java try-catch try-finally

有什么区别

try {
    fooBar();
} finally {
    barFoo();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

tan*_*ens 112

这是两件不同的事情:

  • 只有在try块中抛出异常时才会执行catch块.
  • 如果抛出异常,则始终在try(-catch)块之后执行finally块.

在您的示例中,您没有显示第三个可能的构造:

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
}
Run Code Online (Sandbox Code Playgroud)

并且,就像@codeca在他的评论中所说,没有办法访问finally块中的异常,因为即使没有异常也会执行finally块.

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

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

  • 这样做的一个必然结果是你不能*从`finally`块访问`Throwable`,因为它可能不是*``Throwable`. (11认同)

Mic*_*ngh 11

这些不是变化,它们是根本不同的东西. finally执行,catch只有当发生异常.


The*_*rph 7

最后,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
}
Run Code Online (Sandbox Code Playgroud)

不同于

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}
Run Code Online (Sandbox Code Playgroud)

显著.

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

  1. 最后一块,或者
  2. 一个或多个捕获块,或
  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
}
Run Code Online (Sandbox Code Playgroud)


Kie*_*ran 5

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
}
Run Code Online (Sandbox Code Playgroud)