假设这段代码在20个地方并且始终相同
try {
// do something
} catch (FirstException e) {
// log it
} catch (SecondException e) {
// log it
}
使用这样的东西会不会更好或instanceof
不是很好的解决方案?
try {
// do something
} catch(Exception e) {
logException(e);
}
void logException(Exception e) {
if (e instanceof FirstException) {
// log it
} else if (e instanceof SecondException) {
// log it differently
} else {
// do something with other exception
}
}
我唯一真正讨厌这个解决方案的是捕捉Exception
,这绝不是最好的方式......有没有更好的方法?
答案 0 :(得分:9)
catch (FirstException1 | SecondException | ...)
catch (Exception e)
可能没有任何问题 - 您确实要记录所有例外情况,不是吗?我实际上会建议catch (Throwable t)
,因为OutOfMemoryError
和StackOverflowError
也想要记录。多年来记录异常的经验建议是以相同的方式记录它们。异常消息足以作为人类可读的文本,开发人员真正需要调试的是堆栈跟踪。
小心一件事:永远不要过早捕获异常:在整个应用程序的单个位置捕获它们,所谓的异常障碍 -it位于您输入的级别退出工作单位。
如果检查过的异常在较低级别给您带来麻烦,请将它们包装到RuntimeException
:
try {
...
}
catch (RuntimeException e) {throw e;}
catch (Exception e) {throw new RuntimeException(e);}
仅如果您事先确切知道存在对您的应用程序具有业务级别含义的异常,并且不中止当前的工作单元,但重定向其流量,是否适合在较低级别捕获该异常。实际上,与应用程序代码抛出的所有可能异常的总和相比,这种异常很少见。
答案 1 :(得分:1)
第一种方法肯定更好。通常,捕获Exception
是一种不好的做法,因为在这种情况下,您也会捕获RuntimeException
。
答案 2 :(得分:1)
如果您只需要记录例外,那么前者是干净而且很好的解决方案。
其他第一种方法更好。
答案 3 :(得分:1)
在“重构为模式”一书中,常见的重构之一是“用多态性替换instanceof” - 换句话说,无论何时使用instanceof,都要考虑多态性实际上是否更好。 。
话虽如此,对于这个特殊的问题,Spring的理念是用运行时异常替换已检查的异常(请原谅双关语)。
这个想法是被检查的异常可能被过度使用 - 是可以从中恢复的例外吗?如果是的话,好的。 。 。如果没有,就让它传播到链条上。您可以通过以下方式执行此操作:
创建日志记录方面:
另一件需要考虑的事情是,如果你确实需要在它们发生的那一点上记录这些异常,而不是让它们向上传播, 和 它们会发生在20个不同的地方,他们是一个贯穿各领域的关注点。 。 。您可以使用常规方法重新抛出异常,然后编写一个方面来捕获并记录它们。 。 。 。再次使用Spring使这很容易。