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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26724789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:28:58  来源:igfitidea点击:

How to document (simple) preconditions of a Java method?

javajavadoc

提问by Hoopje

It is often the case that a method imposes constraints on its arguments that cannot be described by the type system. For example, a method might require that some argument be non-null, or some int-typed argument be positive. There might also be more complex preconditions, for example that a certain method was called before, or that a certain object is in some state. What is the best way to document this in Javadoc?

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

For example, suppose I have the following public library function, where the argument cannot be negative:

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

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

I want to document this in such a way that it "stands out" from the rest of the documentation text so that documentation readers know immediately where they have to look. Currently, I do this by adding throwsclauses to the Javadoc:

我想以这样一种方式记录它,使其从文档文本的其余部分“脱颖而出”,以便文档读者立即知道他们必须查看的位置。目前,我通过向throwsJavadoc添加子句来做到这一点:

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

However, this introduces the throwing of the exception into the specification of the method. Now, library users might depend on this behavior in their code. So if I want to change the method in a next version in such a way that also negative parameters are allowed, I might break clients' code.

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

Are there any best practices to document things like this in Javadoc? I have thought of:

是否有任何最佳实践可以在 Javadoc 中记录此类内容?我想过:

  • Describing in the documentation text that the method has undefined behavior if the argument is negative. However, this does not really stand out, so it might be missed by a lot of library users.
  • Using annotations (public void foo(@NonNegative int bar)). However, for this a standard set of annotations would be ideal, and this standard set does not appear to exist.
  • 如果参数为负,则在文档文本中描述该方法具有未定义的行为。然而,这并没有真正突出,所以很多图书馆用户可能会错过它。
  • 使用注释 ( public void foo(@NonNegative int bar))。但是,为此,一组标准的注释将是理想的,并且该标准集似乎不存在。

采纳答案by Jeff Mixon

You seem hesitant to rely on your API's Javadocs to provide exactly that: documentation for your API. While I agree some developers will invariably ignore its warnings, I think historically Javadocs have been entirely adequate in providing sufficient guidance on how to correctly use an API. You can go crazy creating all kinds of custom Annotations, but in the end people will still implement your API incorrectly at times.

您似乎不愿依赖 API 的 Javadocs 来准确提供:API 的文档。虽然我同意一些开发人员总是会忽略它的警告,但我认为从历史上看,Javadocs 在提供关于如何正确使用 API 的足够指导方面已经完全足够了。您可以疯狂地创建各种自定义Annotation,但最终人们有时仍会错误地实现您的 API。

If you did want to go even further beyond what you already have there, you could also implement self-documentingnaming conventions wherever practical. For example:

如果您确实想进一步超越已有的内容,您还可以在任何可行的情况下实施自记录命名约定。例如:

/**
 * 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) {
    ...

Lastly, although your question is about how to document these constraints and not handle them, I will say to not underestimate the value of IllegalArgumentException. This is precisely what it should be used for and engineers should not be afraid to throw this exception to indicate a programming error. Developers aren't going to get far without reading the docs when their implementation doesn't run.

最后,虽然您的问题是关于如何记录这些约束而不是处理它们,但我会说不要低估IllegalArgumentException. 这正是它应该用来做什么的,工程师不应该害怕抛出这个异常来表明一个编程错误。当他们的实现没有运行时,如果不阅读文档,开发人员就不会走得太远。

回答by Matthias Holdorf

You can create custom javadoc tags, i.e. @pre@invand @postfor precondition, invariant and postcondition.

您可以创建自定义的javadoc标记,即@pre@inv@post用于预先条件,INVariant和岗位条件。

Further, Joshua Bloch argues in Effective Java Second Edition:

此外,Joshua Bloch 在 Effective Java Second Edition 中提出:

The doc comment should enumerate all of the method's preconditions, which are the things that have to be true in order for a client to invoke it, and its postconditionsTypically, preconditions are described implicitly by the @throwstagsfor unchecked exceptions; each unchecked exception corresponds to a precondition violation. Also, preconditions can be specified along with the affected parameters in their @paramtags.

该文档注释应该枚举所有方法的的先决条件,这是在为了真正为客户端调用它的东西,它的后置条件一般,前提条件是隐式的描述@throws标签对未检查异常; 每个未经检查的异常都对应于一个前提条件违规。此外,可以在其@param标签中指定先决条件及其受影响的参数

Examples:

例子:

@param index index of element to return; must be non-negative and less than the size of this list @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >= this.size()})

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

Note, that every exceptions begins with if, followed by a clause describing the conditions under which the exception is thrown. (precondition) This is often described with arithmetic expressions.

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