如何知道抛出了哪个异常



我正在检查我们的代码库,有很多这样的语句:

try
{
   doSomething()
} catch (Exception e)
{
}

但我想有一种方法知道哪个异常是由doSomething()抛出的(在doSomething的实现中没有抛出语句),所以我可以捕获该异常,而不是在一般情况下捕获异常,即使有findBugs它也会发出警告REC_CATCH_EXCEPTION

我应该提到,记录异常或将其打印到控制台对我没有帮助,因为在这种情况下,需要花费时间来重现导致这里异常的错误。

谢谢

如果doSomething(例如doSomething() throws IOException)中没有throws语句,则将发生的任何异常都将是RuntimeException的实例。如果您想知道doSomething抛出的异常的确切类,您可以尝试

try {
   doSomething();
} catch (RuntimeException e){
   System.out.println(e.getClass().getName());
}
知道在不实际运行程序的情况下可以抛出哪些运行时异常是困难的。即使doSomething()调用的代码都没有显式抛出,核心java操作也总是可以抛出NullPointerException, ArrayIndexOutOfBoundsException等错误输入。以下是一些想法:
  • 手动挖掘。至少你会知道一些例外。
  • 使用反射来查找任何可以从doSomething访问的throw语句。
  • 运行您的测试用例,并像上面那样记录抛出的异常。好的测试将揭示doSomething调用者应该准备好的重要错误。
  • 去找那些把鱼放在那里的人

在任何情况下,捕获尽可能具体的异常通常是一个好主意,因为当您试图在一个子句中处理所有情况时,您不确切地知道出了什么问题。

您可以1)挖掘doSomething()中的所有代码以及它调用的所有代码,以查看异常处理和可以抛出的RuntimeExceptions,或者2)获取catch (Exception e)并等待它失败。这就是检查异常试图克服的问题,方法是在方法签名中声明调用该方法后必须处理哪些异常。

如果没有throws子句,则该方法不会抛出任何checked异常。该方法的javadoc可能会给出该方法可能抛出的任何未检查异常的信息,但它不必这样做。

为什么首先要捕获异常?

您想捕获编译时异常还是运行时异常?如果您只想捕获编译时的异常,只需删除当前的catch块—您将立即获得错误消息,指出某些异常未被捕获。添加一个异常后,您将看到其他异常的错误消息—您将能够完成捕获代码块抛出的所有可能的异常。

最新更新