我遇到过这两种情况:
在这两种情况下,项目都开始运行,但很快就成了维护(和重构)的开销.
那么关于创建自己的异常类的最佳实践是什么?
小智 14
不要做我公司的开发人员做的事情.有人创建了[sic] InvalidArguementException,它与java.lang.IllegalArgumentException相似,现在我们在(字面上)数百个类中使用它.两者都表明方法已被传递为非法或不恰当的参数.谈论浪费......
Joshua Bloch在" 有效Java编程语言指南" [最新实践的第一手段] 第8章中介绍了这一点.例外 项目42:支持使用标准异常.这是他说的一点,
重用先前存在的异常有几个好处.其中最重要的是,它使您的API更容易学习和使用,因为它符合程序员已经熟悉的既定惯例 [ 我的重点,而不是Bloch的 ].紧接其后的是,使用您的API的程序更容易阅读,因为它们不会被不熟悉的异常所混淆.最后,更少的异常类意味着更小的内存占用和更少的加载类所花费的时间.
最常见的重用异常是IllegalArgumentException.当调用者传入一个值不合适的参数时,这通常是抛出的异常.例如,如果调用者在表示某个操作要重复的次数的参数中传递一个负数,则抛出此异常.
也就是说,你永远不应该抛出异常.Java有一个精心挑选,多样化且目标明确的一系列内置异常,涵盖大多数情况并描述发生的异常,以便您可以纠正原因.
对那些必须在将来维护代码的程序员友好.
我的经验法则是当客户端(调用者)可能合理地想要做一些不同的事情时,根据抛出的异常类型,保证附加的异常类型.但是,通常不需要额外的异常类型.例如,如果调用者正在编写代码
try {
doIt();
} catch (ExceptionType1 ex1) {
// do something useful
} catch (ExceptionType2 ex2) {
// do the exact same useful thing that was done in the block above
}
Run Code Online (Sandbox Code Playgroud)
那么显然不需要额外的异常类型.我经常看到(或者被迫编写)这样的代码,因为被调用的代码在创建新的异常类型时过于热心.
基本上,每项工作都应该有自己的例外。当您捕获异常时,您不会像通常处理对象那样区分不同的实例,因此您需要不同的子类型。我认为使用太多自定义异常的情况几乎不会发生。
一个建议是根据需要创建异常,如果一种异常类型明显与另一种异常类型重复,则通过合并这两种异常来重构代码。当然,如果从一开始就考虑构建异常,这会有所帮助。但一般来说,对于与现有的特定情况异常没有 1:1 对应关系的所有情况都使用自定义异常。
另一方面,NullPointerExceptions 和IndexOutofBoundsExceptions 实际上通常可能是合适的。不过,不要捕获这些(日志记录除外),因为它们是编程错误,这意味着抛出它们后,程序处于未定义状态。