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

If the catch throws exceptions, how should I handle them?

我有一个简单的编码方案,例如:

class A
{

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

我的问题:

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

您可以按照以下方式简单地处理它们...

class A
{
    public static void main(String excep[]) 
    { 
        try{
            //some exception
        }

        catch(Exception e)
        {
            //Again some exception
             try {}
             catch(Exception e){}
        }

        finally
        {
            System.out.println("Finally executed");
             try {}
             catch(Exception e){}
        }
    }
}

这通常在 FileStream 关​​闭示例中完成,如下例所示

FileStream in = new FileStream(f);
finally {
if (input != null) {
   try {
     in.close();
   }catch (IOException exp) {
       System.out.println(exp);
    }
}
  1. 异常可以在catch中处理。
  2. finally 块中有时需要处理异常。
  3. 这不是坏习惯,但如果您想以有意义的方式处理异常,请捕获预期的异常。示例如下。

    public void test() 
    { 
    
    InputStream stream = null;
    
    try{
        // do something
        // initialize stream
        // again do something     
       }
    
     catch(ExpectedException e)
      {
       //Handle the expected exception add a meaningful message here
       //If needed new exception (custom exception) can be thrown to where this
       // method is called and the new exception should be a meaningful to the called
       }
    
      finally
      {
    
        if (stream != null)
    
          try{
           steam.close();
    
          }catch(Exception e){
           //log the error and throw if needed as explained above. 
          }
        }
    

    }

1) 有什么方法可以处理 catch 中的异常吗?如果是,那怎么办?

您可以在 catch() 中使用另一个 try catch 块,或者您也可以抛出异常;

try {
            // some exception
        }

        catch (Exception e) {

            try {
                // Again some exception
                // some exception
            }

            catch (Exception e1) {
                // Again some exception
                throw new RuntimeException();//throwing a runtime exception, you can throw here your required exception
            }
        }

2)如果finally块有异常怎么办,有什么办法处理吗? 与我讨论问题 (1) 的方式相同。

3) 还是在 catch 或 finally 块中出现异常只是糟糕的编程习惯? 可能是

因为你需要在 catch 块中捕获所有异常,这是更好的方法。但是您可以使用另一个 try catch 块来处理 finally 块中的异常。

Try catch 块中 finally 块的示例代码

        finally {
            try {
                System.out.println("Finally executed");
            } catch (Exception final_ex) {
                // handle exception 
            }
        }

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

3) 这不是坏习惯,这是不可避免的

有几件事你应该注意。

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

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

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

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

try-with-resources 抑制关闭时抛出的异常仅在 try 块中抛出异常时才有效,否则关闭时抛出的异常会传播。此行为不同于捕获和记录关闭时抛出的任何内容的旧模式,后者根本不会重新抛出关闭异常。