这两种情况我都经历过:

  • 创建太多自定义异常
  • 使用太多通用异常类

在这两种情况下,项目开始时都还不错,但很快就成为维护(和重构)的开销。

那么创建您自己的异常类的最佳实践是什么?

有帮助吗?

解决方案

Java 专家 写了一篇关于 Java 中的异常, ,并在其中列出了一些创建异常的“最佳实践”,总结如下:

  • 不要编写自己的异常(有很多有用的异常已经成为 Java API 的一部分)

  • 编写有用的异常(如果您必须编写自己的异常,请确保它们提供有关所发生问题的有用信息)

其他提示

不要做我公司开发人员所做的事情。有人创建了一个与 java.lang.IllegalArgumentException 并行的 [原文如此] InvalidArguementException,我们现在在(字面上)数百个类中使用它。两者都表明方法已传递了非法或不适当的参数。谈论浪费...

约书亚·布洛赫 (Joshua Bloch) 在 有效的 Java 编程语言指南 [我的最佳实践圣经] 第 8 章。例外情况 第 42 项:赞成使用标准例外. 。这是他说的一些内容,

重用预先存在的异常有几个好处。其中最主要的是,它使您的 API 更易于学习和使用,因为 它符合程序员已经熟悉的既定约定 [我的重点,不是布洛赫的]。其次,使用 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
}

那么显然不需要额外的异常类型。我经常看到(或被迫编写)这样的代码,因为被调用的代码在创建新的异常类型时过于热心。

如果我找不到一个异常,该异常的名称描述了导致什么类型的错误,那么我会创建自己的异常。

这是我的经验法则。

基本上,每项工作都应该有自己的例外。当您捕获异常时,您不会像通常处理对象那样区分不同的实例,因此您需要不同的子类型。我认为使用太多自定义异常的情况几乎不会发生。

一个建议是根据需要创建异常,如果一种异常类型明显与另一种异常类型重复,则通过合并两者来重构代码。当然,如果从一开始就考虑构建异常,这会有所帮助。但一般来说,对于与现有的特定情况异常没有 1:1 对应关系的所有情况都使用自定义异常。

另一方面, NullPointerExceptionIndexOutofBoundsException实际上通常可能是合适的。不过,不要捕获这些(日志记录除外),因为它们是编程错误,这意味着抛出它们后,程序处于未定义状态。

我自己的经验法则:

我从不抛出异常,除非在单元测试中,当您抛出的内容无关紧要并且没有理由在其上花费任何额外时间时。

我为自定义业务逻辑中发生的错误创建自己的自定义异常类型。尽可能多地使用此异常类型来重铸其他异常,除非客户端需要了解实际发生的情况。

创建自己的异常时:

  • 所有异常必须是 可投掷类

  • 如果要编写由处理或声明规则自动强制执行的检查异常,则需要扩展 异常类

  • 如果要编写运行时异常,则需要扩展运行时异常类。

不要吃掉异常,而是扔掉它们 https://stackoverflow.com/a/921583/1097600

避免创建自己的异常。使用下面已经存在的那些。

IllegalStateException
UnsupportedOperationException
IllegalArgumentException
NoSuchElementException
NullPointerException

抛出未经检查的异常。

例子

public void validate(MyObject myObjectInstance) {
    if (!myObjectList.contains(myObjectInstance))
        throw new NoSuchElementException("object not present in list");
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top