Walt You - 行是知之始

《Effective Java》学习日志(九)74:记录每个方法所抛出的异常

2019-01-13


学习资料主要参考: 《Effective Java Third Edition》,作者:Joshua Bloch



方法抛出的异常的描述是正确使用该方法所需的文档的重要部分。因此,花时间仔细记录每种方法抛出的所有异常(第56项)至关重要。

始终单独声明已检查的异常,并准确记录使用Javadoc @throws标记抛出每个异常的条件。不要采用声明方法抛出它可以抛出的多个异常类的超类的快捷方式。作为一个极端的例子,不要声明公共方法抛出异常,或者更糟糕的是,抛出Throwable。除了拒绝对方法的用户关于它能够抛出的异常的任何指导之外,这样的声明极大地阻碍了该方法的使用,因为它有效地模糊了可能在同一上下文中抛出的任何其他异常。这个建议的一个例外是main方法,它可以安全地声明为抛出异常,因为它只由VM调用。

虽然该语言不要求程序员声明方法能够抛出的未经检查的异常,但明智的做法是将它们作为已检查的异常进行仔细记录。未经检查的异常通常表示编程错误(第70项),并且让程序员熟悉他们可以做出的所有错误有助于他们避免出现这些错误。方法可以有效抛出的未经检查的异常的详细记录列表描述了其成功执行的前提条件。每个公共方法的文档都必须描述其前提条件(第56项),并记录其未经检查的异常是满足此要求的最佳方法。

接口中的方法记录它们可能抛出的未经检查的异常尤为重要。该文档构成了接口的一般合同的一部分,并实现了接口的多个实现之间的共同行为。

使用Javadoc @throws标记来记录方法可以抛出的每个异常,但不要在未经检查的异常上使用throws关键字。 使用您的API的程序员必须知道检查哪些异常以及哪些异常未经检查,因为程序员的责任在这两种情况下有所不同。 由Javadoc @throws标记生成的文档在方法声明中没有相应的throws子句,为程序员提供了一个强大的视觉提示,即未选中异常。

应该注意的是,记录每个方法可以抛出的所有未经检查的异常是理想的,在现实世界中并不总是可以实现的。 当类经历修订时,如果修改导出的方法以抛出其他未经检查的异常,则不会违反源或二进制兼容性。 假设一个类从另一个独立编写的类调用一个方法。 前一类的作者可能会仔细记录每个方法抛出的所有未经检查的异常,但如果后一类被修改为抛出额外的未经检查的异常,那么前一类(未经过修订)很可能会传播 新的未经检查的例外,即使它没有记录它们。

如果由于同样的原因,类中的许多方法抛出异常,则可以在类的文档注释中记录异常,而不是为每个方法单独记录它。 一个常见的例子是NullPointerException。 对于类的文档注释来说,“如果在任何参数中传递空对象引用,则此类中的所有方法都会抛出NullPointerException”,或对该效果的单词。

总之,记录您编写的每个方法可能抛出的每个异常。 对于未经检查和已检查的异常,以及抽象和具体方法,都是如此。 此文档应采用doc注释中的@throws标记的形式。 在方法的throws子句中单独声明每个已检查的异常,但不声明未经检查的异常。 如果您未能记录您的方法可能引发的异常,那么其他人很难或不可能有效地使用您的类和接口。


Content