0

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

4 回答 4

3

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

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

try
{
...
}
catch(Exception1 | Exception2 | Exception3 e)
{
  //Handle
}
catch(Exception4 | Exception5 | Exception6 e)
{
   //Handle differently
}
于 2013-09-05T17:12:08.913 回答
3

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

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

所以:

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

    就像我为什么不喜欢检查异常的背景一样 - 它使这样的代码发生:

    尝试 {
       线程.sleep(1000);
    } 捕捉(InterruptedException e){}
    

    这可以隐藏一些非常烦人的查找程序流相关的错误。在这种情况下,它只是意味着您可能有一些线程控制问题,但在其他情况下,这可能意味着您的代码流“神奇地”在没有任何迹象的情况下消失在方法中间(因为更高级别的 try/catch 发现了异常)。

  • 于 2013-09-05T17:37:09.910 回答
    0

    您可以使用。defaultUncaughtExceptionHandler,但它仅在 Thread 没有设置uncaughtExceptionHandler时触发。

    于 2013-09-05T17:14:37.370 回答
    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来捕获一个块中的所有错误。这使得很难知道特定的异常并阻止对它们进行特定的处理。

    于 2013-09-05T17:18:02.827 回答