立即在 catch 块中重新抛出并使用 finally

Immediately rethrowing in catch block and using finally

我有一个负责记录操作的包装器,名为 OperationWrapper。其结构简单如下:

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     o.execute();
     logOperationFinished();
}

由于"o"操作会抛出异常,logOperationFinished()方法不会总是被调用,因此日志记录无法正常运行。

此外,调用 runOperation() 方法的各种组件会处理这些异常。

为了确保 logOperationFinished() 将始终 运行,我实现了以下结构:

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
       o.execute();
     }
     catch(Exception e){
       throw e; 
     }
     finally{
       logOperationFinished();
     }
}

现在 logOperationFinished() 总是 运行,但我收到来自 IntelliJ 的警告:

Caught exception is immediately rethrown
Reports any catch block where the caught exception is immediately rethrown, without performing any action on it. Such catch blocks are unnecessary or lack error handling.

在我看来,IntelliJ 在发出此警告时并未考虑 finally 块。

我做错了什么或者有更好的方法吗?

谢谢。

是的,你不需要 catch

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
       o.execute();
     }
     finally{
       logOperationFinished();
     }
}

异常是可以恢复的吗?如果不是,抛出错误而不是重新抛出异常可能是合适的。

Scary Wombat 的答案很可能就是您想要的。

throw new Error(e);

Exception vs Error

使用来自 JLS 14.20.2. Execution of try-finally

的 try-finally 块

If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:

  1. If the finally block completes normally, then the try statement completes abruptly for reason R.

  2. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
        o.execute();
     }finally{
       logOperationFinished();
     }
}

如果你想使用 try-catch-finally 仍然不是问题,你可以忽略来自 IntelliJ 的警告,或者从 catch 块中抛出新的异常。

throw new ExceptionYouWantToThrow(e);