Java,特定于类的exception与标准exception

我一直在更新现有的库以抛出exception,以帮助改善使用该库的人员的调试。

起初,我认为我会定义特定于每个类的exception,但事实certificate,大多数exception只是现有运行时exception的扩展(例如, FooNegativeIntArgumentException extends IllegalArgumentExceptionFooNullBarException extends NullPointerException )和特定消息。

定义新例外与使用现有例外的权衡有何不同? 有没有任何惯例/最佳做法?

此外,鉴于需要向后兼容性,大多数(如果不是全部)这些exception都是运行时exception。

这是我对为什么我们有不同类型的exception以及何时创建自定义exception类型的注意事项(注意:这使用.NET类型作为示例,但相同的原则适用于Java和使用结构化error handling的任何其他语言)。 在这里发布完整答案可能太长了,所以我将发布两个关键摘录。

  1. 何时抛出不同类型的exception? 为每个可以以不同方式以编程方式处理的症状抛出不同类型的exception。

  2. 何时创建自定义exception类型? 当您需要使用其他信息注释exception时,创建自定义exception类型,以帮助对症状进行编程处理。

在您的情况下,听起来您的自定义exception类型不会填补使用标准exception可以传达的症状的空白,并且它们不会为编程处理添加任何其他信息,因此不要创建它们。 只需使用标准的。

扩展exception而不添加任何这样的值是完全浪费时间并且导致最好避免的持续维护成本。

使用标准例外。

这并不是说您永远不应该使用自定义exception,而不是在您提供的用例中。

此外,在创建自定义exception时,它们应该与导致它们的条件相关,而不是与它们可能抛出的类相关。 可以将它们与业务/function区域相关联,因为导致exception的错误条件可能以这种方式相关,并且它将提供有用的过滤技术。

来自Effective Java

您应该支持使用标准exception,并使用Java平台库中未经检查的exception集来涵盖您所描述的内容。 重用例外具有以下好处:

使您的API更易于学习和使用,因为它符合程序员已经熟悉的既定惯例

更少的exception类意味着更小的内存占用和更少的加载类所花费的时间。

调用者是否需要捕获FooNegativeIntArgumentException而不是IllegalArgumentException?

我的猜测是它几乎不会发生,所以我会坚持基本的例外,直到你遇到需要这种区别的情况。

交易? 很多工作,很多代码维护和时间就是金钱 。 我建议:只有在需要过滤日志,细粒度exception处理或调试(为特殊exception类型设置断点)时才定义新exception。

我将使用显式定义的exception来为客户端代码提供更多控制。 如果客户端想要,他们可以捕获IllegalArgumentException如上例所示。 如果他们需要更多控制,他们可以捕获各种类型的例外。 例如,考虑一个可能抛出IllegalArgumentException的两个子类的方法。 如果您不是子类,则必须进行字符串解析或其他一些废话来确定抛出exception的实际原因。 用户定义的类型解决了这个问题。