繁体   English   中英

处理可恢复和不可恢复的异常

[英]Handling recoverable and unrecoverable exceptions

希望我能清楚地解释这一点。 如果我的主要方法有很多步骤会产生不同的异常,有些致命,有些则不会,我是否必须分别捕获“可恢复”的异常? 看来这可能会导致很多try / catch块,如下所示:

public static void main (String[] args) {
    try {
        //...
        for (int i=0;someArray.length;i++) {
            try{
                System.out.println("I = " + i);
                doSometing(i);
            } catch (RecoverableException e) {
                //recover, continue, whatever
                //log warning
                                    //keep 
            }
        }//end for loop

        try {
            doSomethingElse();
        } catch (AnotherRecoverableException e) {
            //not fatal, keep on chugging
        }

        //...

        //do more stuff that can throw unrecoverable exceptions
    } catch (UnrecoverableException e) {
        System.out.println("I can't handle this, it's too much!");
        e.printStackTrace();
    }
}

有一个更好的方法吗?

如果您使用的是Java 7,则可以使用管道作为分隔符在catch块中合并异常。 这将减少捕获块的数量。 但是,您需要通过在catch块中放置适当的代码来决定如何处理它们。

在Java 7中,您可以执行以下操作:

try
{
...
}
catch(Exception1 | Exception2 | Exception3 e)
{
  //Handle
}
catch(Exception4 | Exception5 | Exception6 e)
{
   //Handle differently
}

我的模式是让异常传播时,它们代表编程错误,并在可以处理异常时将其处理为与“问题”接近。

问题在于,许多潜在的编程错误都会抛出检查异常,这确实很糟糕(检查异常是一种失败的实验,较新的语言已将其淘汰)。

所以:

  • 处理您可以立即处理的已检查和未检查的异常。
  • 如果您不知道如何处理已检查的异常,请将其作为未检查的异常重新抛出。
  • 任何在主线程或线程中的“顶级”循环都应以“异常”的try / catch / log包围,以确保冒泡的任何异常都不会杀死线程(但请大声记录它,因为它表示未知编程错误!)
  • 不管异常如何都应继续进行的任何关键循环都应在循环结构中包含“异常”的try / catch / log,以使其继续进行。
  • 捕获异常,在此高级别上不抛出。 Throwable包含您可能永远不想捕获的不可恢复的异常。
  • 如果确实必须抛出异常,则认为您希望调用者捕获(尝试避免这种情况,这意味着您正在使用Exception作为代码流!),抛出未经检查的异常,但要对其进行文档化,并使用方法“抛出”未经检查的异常异常(无需处理,但这充当其他文档/提示)。

    就像我为什么不喜欢检查异常的背景一样,它使代码看起来像这样:

    \n 尝试{\n    Thread.sleep(1000);\n } catch(InterruptedException e){}\n

    这可能会隐藏一些令人讨厌的烦恼,以查找程序流相关的错误。 在这种情况下,这仅意味着您可能会遇到一些线程控制问题,但在其他情况下,这可能意味着您的代码流“魔术”消失了,没有任何迹象的中间方法(因为更高级别的try / catch捕获了异常) )。

  • 您可以使用。 defaultUncaughtExceptionHandler ,但仅在线程设置uncaughtExceptionHandler时触发。

    对于7以外的Java版本,一种更干净的方法是处理被调用方法中的异常。 这使代码可读,如下所示:

    doSomething(int i){
     //code
    try{
     //code
    }catch(Exception1 e1){
     //handle
    }
    catch(Exception2 e2){
    //handle
    }
    }
    
    doSomethingElse(){
     //code
     try{
      }catch(Exception1 e1){
     //handle
      }
       catch(Exception2 e2){
        //handle
        }
      }
    
     public static void main (String[] args) {
        for (int i=0;someArray.length;i++) {
         doSometing(i);
        }//end for loop
    
        doSomethingElse();
        }
    

    我不建议使用通用Exception在一个块中捕获所有错误。 这使得很难知道特定的异常并阻止对其进行特定的处理。

    暂无
    暂无

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

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