/*
 * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.lang.annotation;

/**
 * If the annotation {@code @Documented} is present on the declaration
 * of an annotation interface <i>A</i>, then any {@code @A} annotation on
 * an element is considered part of the element's public contract.
 *
 * In more detail, when an annotation interface <i>A</i> is annotated with
 * {@code Documented}, the presence and value of <i>A</i> annotations
 * are a part of the public contract of the elements <i>A</i>
 * annotates.
 *
 * Conversely, if an annotation interface <i>B</i> is <em>not</em>
 * annotated with {@code Documented}, the presence and value of
 * <i>B</i> annotations are <em>not</em> part of the public contract
 * of the elements <i>B</i> annotates.
 *
 * Concretely, if an annotation interface is annotated with {@code Documented},
 * by default a tool like javadoc will display annotations of that interface
 * in its output while annotations of annotation interfaces without
 * {@code Documented} will not be displayed.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

这份代码是 Java 标准库中 @Documented 元注解(meta-annotation)的官方定义。它本身是一个注解,但其作用是用于修饰其他注解,从而影响那些被修饰的注解在生成 API 文档时的行为。

下面我们来详细解析这段代码。

❶ 代码核心作用:控制文档化行为

简单来说,@Documented 注解是一个“开关”,它决定了自定义注解在生成 Java API 文档(Javadoc)时是否可见 。

  • 如果一个自定义注解 @MyAnnotation@Documented 标注了,那么当某个类或方法使用了 @MyAnnotation 时,这个注解信息会出现在为该类或方法生成的 Javadoc 网页中
  • 如果自定义注解 @MyAnnotation 没有@Documented 标注,那么即使用了很多次,它在最终生成的 Javadoc 文档里也不会显示

代码注释中的关键表述是:被 @Documented 标记的注解,其存在和值被视为被注解元素的公共契约(public contract) 的一部分 。这意味着这个注解信息对于 API 的使用者是重要的、需要公开的说明。

❷ 代码结构与元注解解析

这段代码本身也是一个注解声明(public @interface Documented),并且它使用了三个元注解来定义自身的行为,这体现了“元注解注解自身”的自举特性:

@Documented // 它把自己也文档化了
@Retention(RetentionPolicy.RUNTIME) // 它在运行时也可被反射读取
@Target(ElementType.ANNOTATION_TYPE) // 它只能用于注解其他注解
public @interface Documented {
}
  • @Documented 修饰自身:这是一个非常巧妙的设计,它表示 @Documented 注解本身也会被文档化。如果你查看 @Documented 的 Javadoc 页面,你会发现它自己的定义信息 。
  • @Retention(RetentionPolicy.RUNTIME):这指定了 @Documented 注解的保留策略为运行时。这意味着该注解不仅会被编译到字节码文件中,在程序运行时也可以通过反射机制读取到。这对于 Javadoc 等文档工具在处理类文件时能够识别它至关重要 。
  • @Target(ElementType.ANNOTATION_TYPE):这严格限制了 @Documented 注解只能用于标注其他注解类型的定义上。你不能将它用于类、方法或字段上 。

❸ 实际应用示例

假设你正在设计一个框架,并定义了一个用于标记 API 状态的注解:

// 自定义注解,并使用 @Documented 使其在文档中可见
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiStatus {
    String value();
    String since() default "1.0";
}

然后,你在一个工具类中使用了它:

/**
 * 一个提供高级数学计算的工具类。
 */
@ApiStatus(value = "STABLE", since = "2.1")
public class MathUtils {
    // ... 类的方法实现
}

当你为这个项目生成 Javadoc 后,在 MathUtils 类的文档页面上,会明确地显示出 @ApiStatus(value = "STABLE", since = "2.1") 这一行信息。这对于框架或库的使用者来说非常有用,他们能直接从文档中了解到这个类的稳定性和引入版本,而无需去查看源代码 。

反之,如果 @ApiStatus 注解定义时去掉了 @Documented,那么即使在 MathUtils 类上使用了它,生成的文档中也不会出现任何痕迹。

💎 总结

@Documented 元注解是一个用于提升 API 文档完整性的工具。它通过确保重要的注解信息能够被包含在生成的 Javadoc 中,使得 API 的契约更加明确和透明,特别适用于框架、库以及任何需要提供清晰、完整文档的公共 API 设计 。它的存在本身不影响代码的运行时逻辑,其价值主要体现在开发和文档化阶段。

Javadoc 和文档

  • Javadoc 的基本概念:介绍 Javadoc 的定义、作用及其重要性,使用文字和表格对比其与普通注释的区别。
  • 生成 Javadoc 文档的详细步骤:分步骤讲解从编写规范注释到通过命令行、IDE(IntelliJ IDEA 和 Eclipse)及构建工具(Maven 和 Gradle)生成文档的方法,包含示例代码和操作流程图。
  • 生成的 Javadoc 文档的位置与查看:说明文档的默认输出位置、自定义路径设置以及如何查看和浏览生成的 HTML 内容。

Javadoc 详解:从概念到生成 API 文档

1 Javadoc 是什么?

Javadoc 是 Java Development Kit (JDK) 中自带的一款重要工具,它能够从 Java 源代码中的特定格式注释(即以 /** ... */ 包裹的注释)解析并提取信息,最终生成一组描述代码 API(应用程序编程接口)的 HTML 格式网页文档 。简而言之,它实现了 “代码即文档” 的理念,让你在编写代码的同时,就能轻松创建出配套的、专业级的说明文档 。

1.1 Javadoc 的核心价值与作用

Javadoc 远不止是一个简单的文档生成器,它的价值体现在多个层面 :

  • 提升代码可读性和可维护性:清晰的文档让团队成员乃至未来的自己能够快速理解代码的意图和功能,无需逐行分析实现细节。
  • 确立正式的 API 契约:Javadoc 不仅描述“这个方法是干什么的”,更重要的是定义了使用契约,例如调用者需要传入什么参数、方法会返回什么结果、在何种情况下会抛出异常等,这极大地减少了误用和潜在的 Bug 。
  • 无缝的 IDE 集成支持:现代集成开发环境(如 IntelliJ IDEA, Eclipse)会在你编码时,直接显示鼠标悬停处的 Javadoc 信息。这意味着开发者无需离开代码编辑器即可查阅相关 API 的详细说明,显著提升开发效率 。
  • 自动化生成专业文档:它自动化了文档生成过程,避免了手动维护 Word 或 PDF 文档的繁琐和不同步问题。只需一条命令,即可获得一份格式统一、可交叉链接的最新文档 。

1.2 Javadoc 注释与普通注释的区别

理解 Javadoc 注释与普通注释的区别至关重要,下表清晰地展示了它们的核心不同:

特性 Javadoc 注释 (/** ... */) 普通注释 (///* ... */)
解析对象 被 Javadoc 工具解析 被编译器完全忽略
主要目的 生成外部 API 文档,定义契约 为阅读源代码的开发者提供说明
放置位置 仅能紧贴在类、接口、方法、字段等声明之前 代码中的任意位置
内容结构 通常包含描述性文本和结构化标签(如 @param, @return 自由格式的文本

2 如何为项目生成 Javadoc

为项目生成 Javadoc 文档主要包含两个关键阶段:首先是在代码中按照规范编写注释,其次是选择合适的方式运行文档生成工具。下面的流程图展示了完整的步骤和不同生成方式的选择路径:

在这里插入图片描述

下面,我们将详细讲解流程图中每个环节的具体操作。

2.1 第一步:编写规范的 Javadoc 注释

这是生成高质量文档的基础。Javadoc 注释需要遵循特定的格式和标签规范 。

1. 注释位置与基本结构
注释必须放在类、接口、方法、构造器或字段的声明之前,以 /** 开始,以 */ 结束。

2. 注释内容的结构
一个完整的 Javadoc 注释通常包含三部分 :

  • 概要描述:第一句话或第一段话,简要描述该元素的功能。这是一个完整的句子,以英文句号结束。
  • 详细描述:可选的详细说明,可以是一段或多段,进一步解释功能、使用场景或注意事项。
  • 文档标签:以 @ 开头的特殊标记,用于结构化地提供特定信息(如参数、返回值等)。

3. 常用 Javadoc 标签详解
以下是一些最核心和常用的标签 :

标签 适用范围 说明与示例
@param 方法、构造器 描述参数。@param parameterName description
@return 方法(非void) 描述返回值。@return description of the return value
@throws / @exception 方法、构造器 描述可能抛出的异常。@throws ExceptionClass reason
@since 类、方法、字段等 指明该API被引入的版本。@since 1.5
@deprecated 类、方法、字段等 标记API已过时,并提供替代方案。@deprecated explanation and alternative
@see 类、方法、字段等 生成“参见”链接,指向相关的API或资源。
{@code text} 描述中任意处 将文本以代码字体显示,且不解析其中的HTML标签。
{@link package.Class#member} 描述中任意处 在描述中创建一个内联链接,指向特定的类或成员。

4. 代码示例

/**
 * 一个表示银行账户的类。
 * <p>
 * 该类提供了基本的存款、取款和查询余额功能。
 * 它是线程安全的,适用于多线程环境。
 * </p>
 *
 * @author 张三
 * @version 1.2
 * @since 1.0
 */
public class BankAccount {
    private double balance;

    /**
     * 从账户中提取指定金额。
     * <p>
     * 如果提取金额大于当前余额,则提取失败。
     * </p>
     *
     * @param amount 要提取的金额,必须为正数。
     * @return 如果提取成功返回 {@code true},否则返回 {@code false}。
     * @throws IllegalArgumentException 如果 amount 为负数或零。
     * @see #deposit(double)
     */
    public boolean withdraw(double amount) throws IllegalArgumentException {
        // ... 方法实现
    }
}

2.2 第二步:选择并执行生成方式

编写好注释后,可以根据流程图中的选项,选择一种适合你项目环境的方式来生成文档。

方式一:使用命令行工具

JDK 自带了 javadoc 命令,这是最基础的方式 。

  • 基本命令格式
    javadoc -d [输出目录] [源代码文件或包名]
    
  • 常用选项
    • -d <directory>: 指定生成文档的输出目录(必须指定)。
    • -sourcepath <pathlist>: 指定查找源文件的路径。
    • -subpackages <子包列表>: 递归处理指定包及其子包。
    • -encoding UTF-8: 指定源文件编码,避免中文乱码。
    • -author: 在文档中包含 @author 标签信息。
    • -version: 在文档中包含 @version 标签信息。
  • 示例
    • 为当前目录下所有 .java 文件生成文档到 my_docs 文件夹:
      javadoc -d my_docs *.java
      
    • com.example 包及其所有子包生成文档:
      javadoc -d ./docs -sourcepath ./src -subpackages com.example
      
方式二:使用集成开发环境

IDE 提供了图形化界面,操作更简便 。

  • IntelliJ IDEA

    1. 菜单栏选择 Tools -> Generate JavaDoc…
    2. 在弹出窗口中配置:
      • Scope: 选择生成文档的范围(整个项目、模块、文件等)。
      • Output directory: 设置文档输出路径。
      • Other command line arguments: 如需设置编码,可在此输入 -encoding UTF-8 -charset UTF-8
    3. 点击 OK 即可生成。
  • Eclipse

    1. 右键点击项目 -> Export -> Java -> Javadoc
    2. 配置 Javadoc command(通常自动识别)、输出目录等。
    3. 特别注意:如果项目使用 UTF-8 编码,需在 Extra Javadoc options 中输入 -encoding UTF-8 -charset UTF-8 以防止中文乱码 。
方式三:使用项目构建工具

对于 Maven 或 Gradle 项目,将文档生成集成到构建流程中是更专业和自动化的做法 。

  • Maven
    pom.xml 中配置 maven-javadoc-plugin 插件:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <!-- <destDir>${project.build.directory}/site/apidocs</destDir> --> <!-- 可选:自定义输出目录 -->
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    随后在命令行中执行 mvn javadoc:javadoc 即可生成文档 。

  • Gradle
    build.gradle 文件中配置 Javadoc 任务:

    javadoc {
        destinationDir = file("${buildDir}/docs/javadoc") // 自定义输出目录
        source = sourceSets.main.allJava
        options.encoding = 'UTF-8' // 设置编码
    }
    

    随后在命令行中执行 gradle javadoc 即可生成文档 。

3 生成的 Javadoc 文档在哪里?如何查看?

3.1 文档的输出位置

  • 默认/常见位置:无论通过哪种方式生成,Javadoc 文档的默认输出位置通常都在你指定的输出目录(通过 -d 选项或在 IDE/构建工具中配置)。命令行和 IDE 方式下,常见的自定义目录是项目根目录下的 docdocs 文件夹 。构建工具方式下,Maven 默认输出到 target/site/apidocs,Gradle 默认输出到 build/docs/javadoc
  • 定位方法:生成成功后,只需在文件管理器中打开你为 -d 选项指定的那个目录,或者查看构建工具的标准输出路径即可。

3.2 查看与浏览文档

生成的 Javadoc 文档是一组标准的 HTML 网页 。

  1. 使用任何网页浏览器(如 Chrome, Firefox, Edge)打开输出目录中的 index.html 文件。这个文件是整个 API 文档的入口页。
  2. 在浏览器中,你可以通过左上方的包列表、下方的类列表,或者顶部的导航栏来浏览整个项目的文档结构。点击具体的类或方法名,即可查看其详细的描述、参数说明、返回值信息等 。

总结

Javadoc 是 Java 开发者必备的强大工具,它将代码和文档紧密结合,极大地提升了代码的可理解性、可维护性和团队协作效率。通过遵循规范的注释格式,并灵活运用命令行、IDE 或构建工具,你可以轻松为项目生成专业、清晰的 API 文档。请记住,优秀的代码配合优秀的文档,才能构建出真正健壮和可持续的软件系统

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐