避免 Java 记录中的 Javadoc 重复

Gar*_*son 7 java javadoc java-record

新的 Javarecord应该会减少样板文件。我可以使用和组件快速创建一个不可变的FooBar类,而不必担心局部变量、构造函数值复制和 getter,如下所示:foobar

\n
/**\n * Foo bar record.\n */\npublic record FooBar(String foo, String bar) {\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当然,我想记录记录组件是什么,这样它们就会显示在生成的 Javadoc 中!所以我添加这个:

\n
/**\n * Foo bar record.\n * @param foo That foo thing; cannot be <code>null</code>.\n * @param bar That bar thing; cannot be <code>null</code>.\n */\npublic record FooBar(String foo, String bar) {\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这很好用\xe2\x80\x94记录组件显示在文档中。

\n

除了几乎 100% 的记录之外,作为一名优秀的开发人员,我当然需要验证foobar确保它们不为空,对吧?(对。)记录很容易做到这一点:

\n
/**\n * Foo bar record.\n * @param foo That foo thing; cannot be <code>null</code>.\n * @param bar That bar thing; cannot be <code>null</code>.\n */\npublic record FooBar(String foo, String bar) {\n\n  /** Constructor for argument validation and normalization. */\n  public FooBar {\n    Objects.requireNonNull(foo);\n    Objects.requireNonNull(bar);\n  }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在,由于我正在使用-Xdoclint:all,我收到一条警告,因为该构造没有记录其(隐式)参数:

\n
[WARNING] Javadoc Warnings\n[WARNING] \xe2\x80\xa6/FooBar.java:xx: warning: no @param for foo\n[WARNING] public FooBar {\n[WARNING] ^\n[WARNING] \xe2\x80\xa6/FooBar.java:xx: warning: no @param for bar\n[WARNING] public FooBar {\n[WARNING] ^\n[WARNING] 2 warnings\n
Run Code Online (Sandbox Code Playgroud)\n

如果你说“关掉就行-Xdoclint:all”,那么你就没有抓住重点。该警告是有效的,因为在生成的 Javadoc 中确实没有显示构造函数的文档!如果有构造函数,应该有参数的文档。所以我被迫进行旧的复制和粘贴:

\n
[WARNING] Javadoc Warnings\n[WARNING] \xe2\x80\xa6/FooBar.java:xx: warning: no @param for foo\n[WARNING] public FooBar {\n[WARNING] ^\n[WARNING] \xe2\x80\xa6/FooBar.java:xx: warning: no @param for bar\n[WARNING] public FooBar {\n[WARNING] ^\n[WARNING] 2 warnings\n
Run Code Online (Sandbox Code Playgroud)\n

等等,减少样板文件发生了什么?样板文件看起来几乎和以前一样糟糕,甚至更糟,因为现在它完全是重复的。当然,也许语义略有不同,所以也许我可以调整措辞。也许一个应该说“永远不可能null”,另一个应该说“抛出异常,如果null,但实际上,这并不理想。

\n

当我重写方法时,Javadoc 并不是那么不智能。如果我为带有注释的方法保留 Javadoc @Override,那么 Javadoc 会从重写的类或接口复制文档。如果我决定要调整文档,我什至有一个{@inheritDoc}Javadoc 标记,允许我从我要重写的方法复制文档。

\n

这里有什么解决办法吗?有没有办法告诉 Javadoc 使用构造函数的主记录参数文档,反之亦然?我可以使用一些 Javadoc 标签来使其自动发生吗?因为目前的情况远非理想。

\n

Gar*_*son 4

我刚刚为此提交了 OpenJDK 改进请求。该请求现已在JDK-8309252上公开,尽管尚不清楚他们是否已验证 Javadoc 注释是否已复制到显式记录构造函数,或者是否仅删除了警告。(我发送了后续查询,但尚未收到任何回复或票证更新。)

\n

以下是我的请求的摘录:

\n
\n

请改进 Javadoc,以便如果为记录提供了构造函数,则对于每个缺失的@paramJavadoc 将使用@param记录描述中提供的构造函数。这类似于@Override如果没有给出文档,Javadoc 已经复制了方法的方法 API 文档。

\n

\xe2\x80\xa6

\n

Javadoc(现在)正确处理的类似情况是重写方法时。开发人员可能会留下用 注释的方法的文档@Override,Javadoc 将从重写的类或接口复制文档。在这种情况下,不需要注释@Override,因为语义是上下文隐含的。

\n

{@inheritDoc}当开发人员想要复制重写方法的文档然后添加到其中时,Javadoc 提供了一种机制。也许 Javadoc 可能会提供一种{@defaultDoc}{@recordDoc}一些类似的机制来添加到记录级文档中。

\n

@param仍然默认情况下,如果根本没有为自定义构造函数提供任何文档,Javadoc应该像没有提供自定义构造函数时那样复制记录级文档,并且不会发出任何 doclint 警告。

\n
\n

同时,对于解决方法,似乎(请参阅JDK-8275351)在 Java 18 中我可以使用 来抑制警告@SuppressWarnings("doclint:missing")。我还没有验证这一点。今年晚些时候,当我在 Java 21 发布后迁移到它时,我将更新这个答案。

\n

2023-11-23 更新:我已经确认 Java 21 带来了改进。如果记录字段本身没有记录,则会发出警告,但如果存在验证构造函数,无论它是否具有 Javadoc 注释,都不会生成警告。不幸的是,正如 Holger 提到的,记录级字段文档没有被复制(反映了 JDK- 8309252的未完成状态)。相反,样板短语的效果是“价值foo相反,插入了如果提供了主要文档进行验证,我仍然会发出“警告:无评论”。如果我确实提供了验证构造函数的主要描述,则根本不会复制任何字段文档。至少警告的抑制是一种进步。

\n

  • [最近的评论](https://bugs.openjdk.org/browse/JDK-8309252?focusedCommentId=14586946&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14586946)表明只有警告已被删除,但参数文档未复制。 (2认同)