我正在检查我们的代码库,有很多这样的语句:
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块—您将立即获得错误消息,指出某些异常未被捕获。添加一个异常后,您将看到其他异常的错误消息—您将能够完成捕获代码块抛出的所有可能的异常。