JEP 467: Java 增强 Markdown 支持的文档功能

JEP 467:Markdown 文档注释

JEP 467(Markdown 文档注释)已从 Proposed 状态提升为 Targeted,并计划在 JDK 23 中实现。该功能提议允许在 JavaDoc 文档注释中使用 Markdown 语法,而不是传统的 HTML 和 JavaDoc @ 标签的组合。这将使文档注释在源代码中更易编写和阅读。

主要目标

该更新的主要目标是简化和改善 Java 源代码中文档注释的编写和阅读过程。通过引入 Markdown,开发者可以避免使用复杂的 HTML 和 JavaDoc 标签。现有的文档注释将不受影响,确保向后兼容性。

扩展的编译器 Tree API

该更新还扩展了编译器 Tree API,使其他分析文档注释的工具能够有效地处理 Markdown 内容。

手动更新要求

需要注意的是,该更新不包括自动将现有文档注释转换为 Markdown 语法的功能。开发者需要手动更新其文档以利用新功能。

传统 JavaDoc 注释的问题

传统的 Java 文档注释使用 HTML 和 JavaDoc 标签,这在 1995 年是一个实用的选择,但随着时间的推移,变得不再方便。HTML 冗长且难以手写,尤其是对不熟悉 HTML 的开发者。内联的 JavaDoc 标签,如 {@link}{@code},也较为繁琐,通常需要参考文档以正确使用。

Markdown 的优势

相比之下,Markdown 是一种轻量级的标记语言,易于阅读和编写。它支持简单的文档结构,如段落、列表、样式化文本和链接,使其成为 HTML 在文档注释中的合适替代品。此外,Markdown 允许包含 HTML 以实现其不支持的结构,提供了灵活性,同时减少了复杂性。

示例对比

以下是一个使用传统 JavaDoc 注释格式的 java.lang.Object.hashCode 方法的文档注释示例:

/**
 * Returns a hash code value for the object. This method is
 * supported for the benefit of hash tables such as those provided by
 * {@link java.util.HashMap}.
 * <p>
 * The general contract of {@code hashCode} is:
 * <ul>
 * <li>Whenever it is invoked on the same object more than once during
 *     an execution of a Java application, the {@code hashCode} method
 *     must consistently return the same integer, provided no information
 *     used in {@code equals} comparisons on the object is modified.
 *     This integer need not remain consistent from one execution of an
 *     application to another execution of the same application.
 * <li>If two objects are equal according to the {@link
 *     #equals(Object) equals} method, then calling the {@code
 *     hashCode} method on each of the two objects must produce the
 *     same integer result.
 * <li>It is <em>not</em> required that if two objects are unequal
 *     according to the {@link #equals(Object) equals} method, then
 *     calling the {@code hashCode} method on each of the two objects
 *     must produce distinct integer results.  However, the programmer
 *     should be aware that producing distinct integer results for
 *     unequal objects may improve the performance of hash tables.
 * </ul>
 *
 * @implSpec
 * As far as is reasonably practical, the {@code hashCode} method defined
 * by class {@code Object} returns distinct integers for distinct objects.
 *
 * @return  a hash code value for this object.
 * @see     java.lang.Object#equals(java.lang.Object)
 * @see     java.lang.System#identityHashCode
 */

使用 Markdown 语法后,相同的文档注释可以写成:

/// Returns a hash code value for the object. This method is
/// supported for the benefit of hash tables such as those provided by
/// [java.util.HashMap].
///
/// The general contract of `hashCode` is:
///
///   - Whenever it is invoked on the same object more than once during
///     an execution of a Java application, the `hashCode` method
///     must consistently return the same integer, provided no information
///     used in `equals` comparisons on the object is modified.
///     This integer need not remain consistent from one execution of an
///     application to another execution of the same application.
///   - If two objects are equal according to the
///     [equals][#equals(Object)] method, then calling the
///     `hashCode` method on each of the two objects must produce the
///     same integer result.
///   - It is _not_ required that if two objects are unequal
///     according to the [equals][#equals(Object)] method, then
///     calling the `hashCode` method on each of the two objects
///     must produce distinct integer results.  However, the programmer
///     should be aware that producing distinct integer results for
///     unequal objects may improve the performance of hash tables.
///
/// @implSpec
/// As far as is reasonably practical, the `hashCode` method defined
/// by class `Object` returns distinct integers for distinct objects.
///
/// @return  a hash code value for this object.
/// @see     java.lang.Object#equals(java.lang.Object)
/// @see     java.lang.System#identityHashCode

Markdown 文档注释的语法

Markdown 文档注释使用 /// 作为每行的开头,而不是传统的 /** ... */ 语法。这有助于避免与嵌入的 /* ... */ 注释冲突,这在文档注释中越来越常见。

使用的 Markdown 解析器

该实现使用的是 CommonMark 变体,并增强了支持链接到程序元素和简单的 GFM(GitHub 风格的 Markdown)表格功能。JavaDoc 标签仍然可以在 Markdown 文档注释中使用,确保保留现有的 JavaDoc 功能。

新的树节点类型

解析后的文档注释由编译器 Tree API 中的 com.sun.source.doctree 包表示。为了处理未解释的文本,引入了新的树节点类型 RawTextTree,并添加了新的树节点种类 DocTree.Kind.MARKDOWN,用于指示 Markdown 内容。该实现利用了 commonmark-java 库将 Markdown 转换为 HTML。

总结

引入 Markdown 支持 JavaDoc 注释标志着 Java 文档能力的显著提升,使其更易于访问和维护。这一变化预计将提高开发者的生产力,并改善 Java 文档的整体可读性。

阅读 36
0 条评论