如何记录Java方法的(简单)前提条件?

Hoo*_*pje 7 java javadoc

通常情况下,方法对其参数施加约束,而类型系统无法对其进行描述.例如,方法可能要求某些参数为非null,或者某些int类型的参数为正数.可能还存在更复杂的前提条件,例如之前调用某个方法,或者某个对象处于某种状态.在Javadoc中记录这个的最佳方法是什么?

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

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

我希望以这样的方式记录它,使其从文档文本的其余部分"脱颖而出",以便文档读者立即知道它们必须查看的位置.目前,我通过向throwsJavadoc 添加子句来实现此目的:

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

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

是否有任何最佳实践来记录Javadoc中的这类内容?我想到了:

  • 在文档文本中描述如果参数为负,则该方法具有未定义的行为.但是,这并没有真正脱颖而出,因此许多图书馆用户可能会错过它.
  • 使用注释(public void foo(@NonNegative int bar)).但是,对于此,标准的注释集将是理想的,并且该标准集似乎不存在.

Jef*_*xon 5

您似乎对依赖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) {
    ...
Run Code Online (Sandbox Code Playgroud)

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