如何记录(简单)Java方法的先决条件?

通常情况下,一种方法对其类型系统无法描述的参数施加约束。 例如,一个方法可能需要某些参数为非空值,或者某些int型参数为正值。 也可能有更复杂的先决条件,例如之前调用某种方法,或某个对象处于某种状态。 在Javadoc中记录这一点的最佳方式是什么?

例如,假设我有以下公共库函数,其中参数不能为负数:

public void foo(int bar) {
    if (bar < 0) {
        throw new IllegalArgumentException("Negative bars cannot be food.");
    }
    ...
} 

我想以这样一种方式记录它,使其从文档的其他文本中“脱颖而出”,以便文档读者立即知道他们必须看的地方。 目前,我通过向Javadoc添加了throws子句来实现这一点:

/**
 * Foos a bar.
 * @param bar  the bar to be food
 * @throws IllegalArgumentException  if bar is negative
 */
public void foo(int bar) {
    ...

但是,这引入了将异常抛出到方法的规范中。 现在,库用户可能依赖于他们的代码中的这种行为。 因此,如果我想在下一个版本中更改方法,并允许负面参数,我可能会破坏客户端的代码。

在Javadoc中是否有任何最佳实践来记录这样的事情? 我曾想过:

  • 在文档文本中描述如果参数为负数,则该方法具有未定义的行为。 但是,这并没有真正突出,所以很多图书馆用户可能会忽略它。
  • 使用注释( public void foo(@NonNegative int bar) )。 然而,对于这个标准的注释集是理想的,而这个标准集似乎并不存在。

  • 您似乎犹豫依靠您的API的Javadocs来准确提供:API的文档。 虽然我同意一些开发人员总是会忽略它的警告,但我认为历史上,Javadocs已经完全提供了有关如何正确使用API​​的充分指导。 你可以疯狂地创建各种自定义Annotation ,但最终人们仍然会错误地实现你的API。

    如果你确实想要超越你已有的东西,你也可以在任何可行的地方实现自我记录的命名约定。 例如:

    /**
     * Foos a positive bar.
     * @param positiveBar  the non-zero,non-negative bar to be food
     * @throws IllegalArgumentException  if bar is zero or negative
     */
    public void foo(int positiveBar) {
        ...
    

    最后,虽然你的问题是关于如何记录这些约束而不处理它们,但我会说不要低估IllegalArgumentException的价值。 这正是它应该使用的,工程师不应该害怕抛出这个异常来指示编程错误。 开发人员在实施不运行的情况下如果没有阅读文档就不会走得太远。


    您可以创建自定义的javadoc标记,即@pre @inv@post前期状态,INV ariant和后置条件。

    此外,Joshua Bloch在Effective Java第二版中提出:

    doc注释应该枚举所有方法的前提条件,这些前提条件必须是真实的,以便客户端调用它,以及它的后置条件通常, 前提条件由@throws标记隐式描述,用于未检查的异常; 每个未经检查的异常对应于违反先决条件。 此外, 还可以在其@param标签中指定前提条件以及受影响的参数

    例子:

    要返回的元素的@param索引索引; 必须是非负数并小于此列表的大小@throws IndexOutOfBoundsException如果索引超出范围({@code index <0 || index> = this.size()})

    请注意,每个异常都以if开头,后跟一个描述抛出异常的条件的子句。 (先决条件)这通常用算术表达式来描述。

    链接地址: http://www.djcxy.com/p/8853.html

    上一篇: How to document (simple) preconditions of a Java method?

    下一篇: Convention for marking methods as pure functions in Java