处理方法中的多个异常

时间:2009-12-02 21:02:30

标签: java exception exception-handling methods

我目前正致力于维护一段有点“异常快乐”的代码。基本上,任何方法或任何东西抛出异常。我将努力解决这个问题,但与此同时,我想知道在较小的代码块中处理个别异常的最佳方法是什么,例如方法。做这样的事情更好:

public void aMethod()
  try {
    //Lots of code in here.  Many lines.
  } catch(Exception e) {
    // TODO - Handle All Exceptions, but fairly generically
  }
}

或类似的东西:

public void bMethod() {
  try {
    // One line of code.
  } catch(Exception e) {
    // TODO - Handle a specific Exception (may even involve rethrowing it with more information)
  }

  // More code.

  try {
    // Another line of code.
  } catch(Exception e) {
    // TODO - Handle another specific exception.
  }
}

我意识到这是一个非常基本的问题,但是在看了几百个带有异常的方法之后,我开始想知道如何最好地处理所有这些方法以及最佳实践可能在这里。< / p>

5 个答案:

答案 0 :(得分:6)

首先,您应该只将代码放在try / catch块中,这是非常值得的。例如,具有意外值不一定是例外,但尝试从不存在的文件中读取是。

要回答您的主要问题,您应该将异常代码放在同一个try {}块中,并在主要尝试后按多个catch块中的粒度顺序捕获特定问题。

//Regular code that doesn't need to be covered by a try/catch block

try {

  //critical code only

} catch (NullPointerException npe) {
  //Code
} catch (RandomException re) {
  //code
} catch (Exception e) {
  //code
}

答案 1 :(得分:2)

你的问题的答案是:它取决于。

  • 如果try块中的代码是连贯的,在发生错误的情况下继续进行是没有意义的,第一种方法是最好的
  • 如果代码采取相对无关的单独步骤(例如解析数字)并且可以在不中止方法的其余部分的情况下恢复,那么秒数appraoch就有意义了

关于您继承的代码的一般说明;听起来好像异常被滥用来传递状态,我会重构,以便在可以处理它们的位置捕获异常并引入返回值或属性来处理状态。

答案 2 :(得分:1)

您的bMethod不是非常有用的插图。尝试重新编写它。无论如何,你有两个选择:

  1. 捕获异常并记录它们。
  2. 捕获异常和throw new RuntimeException(ex)(重新抛出运行时异常,将原始异常设置为原因)
  3. 此外,您需要区分异常。如果您的系统有许多自定义异常,则可能是出于某种原因定义了它们,并且在抛出其中一个异常时会出现特定的行为。

答案 3 :(得分:0)

如果try / catch块没有添加有用的信息,只需允许该方法抛出异常并将其处理到调用者可以明白地执行异常操作的地方。这可以显着减少尝试/捕获的数量(按一个数量级)。

BTW重新抛出任何异常的技巧是。

try {
   // do something
} catch (Throwable t) {
   Thread.currentThread().stop(t); // rethrow any exception.
}

答案 4 :(得分:0)

除了已经提出的建议之外,您可能还想考虑从函数的“肉”中提取try / catch块。

public void delete(Page page) {
    try {
        deletePageAndAllReferences(page);
    }
    catch (Exception e) {
        logError(e);
    }
}

private void deletePageAndAllReferences(Page page) throws Exception {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
}

private void logError(Exception e) {
    logger.log(e.getMessage());
}

这使您可以将注意力集中在您真正感兴趣的功能上,而不会遇到异常处理。