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

时间:2013-09-05 17:10:57

标签: java

希望我能清楚地解释清楚。如果我有一个主要方法有很多步骤可以产生不同的异常,有些是致命的,有些则不是,我是否必须分别捕获“可恢复的”异常?看起来这可能导致很多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();
    }
}

有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

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

在Java 7中,您可以这样做:

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

答案 1 :(得分:3)

我的模式是让异常在表示编程错误时传播,并在处理它们时将其处理为与“问题”紧密相关。

问题在于许多潜在的编程错误抛出了非常糟糕的已检查异常(已检查的异常是一种失败的实例,新的语言已经摆脱它们)。

所以:

  • 处理您可以立即处理的已检查和未检查的异常。
  • 如果您不知道如何处理已检查的异常,请将其重新抛出为未经检查的异常。
  • 主要或线程中的任何“顶级”循环应该被“异常”的try / catch / log包围,以确保任何冒泡的异常都不会杀死该线程(但是日志)它响亮,因为它代表了一个未知的编程错误!)
  • 任何应该继续的关键循环,无论异常如何,都应该在循环结构中有一个“异常”的try / catch / log,这样它就会继续。
  • 捕捉异常,而不是在这个高级别可抛出。 Throwable包括您可能永远不想捕获的不可恢复的异常。
  • 如果你真的必须抛出异常,你认为你希望调用者能够捕获(试图避免这种情况 - 这意味着你正在使用Exceptions作为代码流!),抛出一个未经检查的异常但是记录它并且有方法“抛出”未经检查的异常(它不需要处理,但这可以作为附加文档/提示)。

    正如我不喜欢检查异常的背景一样 - 它会使这样的代码发生:

    try {
       Thread.sleep(1000);
    } catch(InterruptedException e) {}
    

    这可以隐藏一些令人讨厌的烦恼,以找到与程序流相关的错误。在这种情况下,它只是意味着你可能有一些线程控制问题,但在其他情况下它可能意味着你的代码流“神奇地”消失了中间方法没有任何迹象(因为更高级别的尝试/捕获异常)。

  • 答案 2 :(得分:0)

    你可以使用。 defaultUncaughtExceptionHandler,但只有在线程没有设置uncaughtExceptionHandler时才会触发。

    答案 3 :(得分:0)

    对于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来捕获一个块中的所有错误。这使得很难知道具体的异常并阻止对它们的具体处理。