如果 catch 抛出异常,我应该如何处理它们?

Avi*_*vin 5 java exception-handling exception

我有一个简单的编码场景,如:

class A
{

    public static void main(String[] args) 
    { 
        try{
            //some exception
        }
        catch(Exception e)
        {
           //Again some exception
        }
        finally
        {
            System.out.println("Finally executed");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 有没有办法处理 catch 中的异常?如果是,那么如何?
  2. 如果 finally 块有异常怎么办,有没有办法处理它们?
  3. 或者在 catch 或 finally 块中出现异常只是糟糕的编程习惯吗?

Nat*_*hes 1

1 和 2)是的,您可以通过嵌套 try 块或让异常抛出(取决于情况需要)来完成这两个操作。

3)这不是不好的做法,而是不可避免的

您应该注意以下几件事。

一个潜在的问题是异常屏蔽。当您从 catch 或 finally 块抛出异常时,这将取代任何原始异常。如果您有某种 Closeable(例如 InputStream 或 JDBC 对象),您必须在 finally 块中关闭资源,如果您让该异常被抛出,那么您将丢失原始异常,该异常会告诉您实际出了什么问题。

另一件需要考虑的事情是,对于在 finally 块中抛出异常的情况,您是否希望传播异常。对于 JDBC 示例,一旦事务已经提交,那么如果在关闭连接时抛出异常,则与业务逻辑无关,这只是一个麻烦。因此,处理此类事情的常见方法是捕获finally块中的异常并记录它,但不要重新抛出它。

try -with-resources功能是修复异常屏蔽的尝试。如果在 try 中抛出异常后,在 finally 块中抛出异常,则 close 时的异常将添加到原始异常上,您可以通过该Throwable#getSuppressed方法访问它。

try-with-resources 还提供了一种避免 try-finally 块嵌套的方法,您可以声明多个可关闭对象,它们将按后进先出的顺序关闭。

仅当 try 块中抛出异常时,try-with-resources 对关闭时引发的异常的抑制才有效,否则关闭时引发的异常将被传播。此行为与捕获并记录关闭时引发的任何内容的旧模式不同,后者根本可以防止重新引发关闭异常。