摘要:本文介绍了Java文档注释的格式和常用标签,帮助开发者规范编写代码文档。文档注释以/**开头,包含描述文本和标签,支持块标签(如@author、@version、@see等)和内联标签(如{@code})。文档注释配合javadoc工具或IDEA可自动生成HTML格式的API文档,是Java开发中重要的文档规范。
一、前言
对于任何一个Java开发人员来说,都应该熟悉Java中三种类型的注释:单行注释,多行注释,文档注释。
文档注释能够将有关程序的信息嵌入到程序本身中。然后,就可以使用 JDK 提供的 javadoc 工具程序来提取这些信息,并将其放入一个 HTML 文件中。文档注释使得记录程序信息变得十分便捷。我相信作为Java开发者你肯定见过使用此类注释的文档,因为这就是 Java API 库的编写方式。
二、文档注释的格式
文档注释可以用于类、接口、字段、构造方法、方法、包和模块。在所有情况下,文档注释必须放在被描述的元素之前。通常的格式如下:
/**
* 对元素的{@inlineTag}描述内容
*
* @blockTag1 描述1
* @blockTag2 描述2
* @blockTag3 描述3
*/
在上面的注释片段中,出现了一些带@符号的字符串,这些称之为标签(Tag),按照标签的写法,可以分为两种:
- 块标签(Block Tag,也称为独立标签),以"@"符号开头的文档标签,并且必须在单独的一行中使用。
- 内联标签(Inline Tag),以大括号开头的标签,例如 {@code},可以在任何的描述文本中使用。
文档注释的第一行以/**开头,随后的行可以包含一个或多个各种 @标签,每个 @标签必须从新行的开头开始,或者紧跟在一行开头的多个星号之后。相同类型的多个标签应组合在一起。例如,如果您有三个 @see 标签,请一个接一个地放置它们。以下是来自JDK中的Object类:
/**
* Class {@code Object} is the root of the class hierarchy.
* Every class has {@code Object} as a superclass. All objects,
* including arrays, implement the methods of this class.
*
* @see java.lang.Class
* @since 1.0
*/
public class Object {
// 内容省略
}
可以看到,在 Object 类的文档注释中,第 2 到 4 行的文本中使用了两次内联标签 {@code},在第 6 行和第 7 行分别使用了块标签 @see 和 @since。
javadoc 工具能识别多个标签,这些特定的标签有助于javadoc工具产生更好的文档。
也可以在文档注释中使用其他标准的 HTML 标签。但是,某些标签(例如标题)不应使用,因为它们会破坏 javadoc 生成的 HTML 文件的外观。
以下我按照块标签和内联标签两大类对每个标签的具体使用进行介绍,为了看起来更加简单,这里的示例并无特定的概念,纯粹是为了展示各种标签的用法。
三、标签详解
块标签
1、@author
@author 标签用于记录程序元素(类,方法等)的作者信息。其语法如下:
@author 信息
这里的信息部分通常会是作者的姓名。在执行 javadoc 时,还需要指定 -author 选项才能将 @author 字段包含在 HTML文档中。示例:
/**
* 用于演示author标签的使用
*
* @author 老谭
*/
public class AuthorTag {
}
当然这种如果是多个,可以并列再加一行@author
/**
* 用于演示author标签的使用
*
* @author 老谭
* @author 其他人
*/
public class AuthorTag {
}
用于方法上也是可行的:
/**
* 用于演示author标签的使用
*
* @author 老谭
*/
public void method() {
}
2、@version 与 @since
@version标签用于指定程序元素的版本。其语法结构如下:
@version 信息
信息通常为版本号,例如 1.5。在执行 javadoc 时,需要指定 -version 选项才能将 @version 信息包含在 HTML 文档中。
@since标签表示某个元素是在某一特定版本中引入的。它具有以下语法:
@since 版本
其中,版本 是一个字符串,用于指明此功能在哪个版本或发布中引入的。示例如下:
/**
* 用于演示@version与@since标签的使用
*
* @author 老谭
* @version 1.5
* @since 1.2
*/
public class VersionAndSinceTag {
public void method() {
}
}
@since 1.2 表示 VersionAndSinceTag 类是在版本 1.2 才引入的。
3、@see
@see标签用于提供额外信息的引用。有三种常用的格式:
@see "纯文本"
@see <a href="绝对或相对的 URL">label</a>
@see 模块名/包.类名#成员名称 [label]
在第一种格式中,引用被指定为用双引号括起来的文本。javadoc 工具会在 “See Also” 部分添加指定的文本,但不会添加任何链接。
See Also在产生的中文文档中翻译为另请参阅
在第二种格式中,使用 HTML 超链接标签( 标签)指定引用。javadoc 工具会生成一个指向指定 URL 的超链接。如果指定了label,则显示指定的label作为链接文本。
在第三种形式中,引用指定为一个类、一个接口、一个字段、一个构造方法或一个方法。
请注意,如果引用的是字段、构造方法或方法,其名称前面会有一个井号(#),而不是一个点。
javadoc 工具会生成一个带有指定label作为可见文本的链接到该引用。标签是可选的。如果省略label,该工具会使用从 @see 标签的第一个参数派生的适合文本作为链接。
对程序元素的引用可以使用完全限定名或部分名称。工具会使用与 Java 编译器相同的规则来解析程序元素的部分名称。
/**
* 用于演示@see标签的使用
*
* @author 老谭
* @see "Oracle官网"
* @see <a href="http://www.oracle.com">Oracle官网</a>
* @see String
* @see java.util.List
* @see java.util.List#add(Object) 增加元素
*/
public class SeeTag {
}
4、@deprecated
@deprecated 标签用于标明被描述的元素已被弃用,但是这并不表示该元素不可用,只是有更好的替代方案。建议配合使用 @see 或 {@link} 标签来告知程序员可用的替代方案。其语法如下:
@deprecated 描述信息
其中,描述信息是描述弃用情况的说明。@deprecated 标签可用于字段、方法、构造方法、类、模块和接口的文档中。以下代码在类上使用 @deprecated 标签:
/**
* 用于演示@deprecated标签的使用
*
* @deprecated 该类存在性能问题,使用{@link java.util.HashMap}代替
*/
public class DeprecatedTag {
}
5、@param
@param标签用于描述方法参数。其语法如下:
@param 参数名 参数的描述
@param 标签仅能在方法、构造方法、泛型类或接口的文档注释中使用。
用于方法参数的描述及泛型类的类型参数描述:
/**
* 用于@param标签的使用
*
* @param <E> 这个类中成员data的类型
* @author 老谭
*/
public class ParamTag<E> {
E data;
/**
* 设置名称和描述
*
* @param name 名称
* @param desc 描述
*/
public void setName(String name, String desc) {
}
}
第 4 行中 @param 描述了声明泛型类时使用的类型参数,第 13,14 行则对setName方法的参数进行了描述。
6、@return
@return标签用于描述方法的返回值。如果方法没有返回值,则不应该使用它。它的使用形式如下:
@return 返回值描述
返回值描述用于说明方法返回值的类型及其含义。因此,该标签仅能用于方法的文档说明中。
/**
* 用于演示@return标签的用法
*
* @author 老谭
*/
public class ReturnTag {
/**
* 计算长方形的面积
*
* @param length 长方形的长度
* @param width 长方形的宽度
* @return 长方形的面积,如果长度或宽度有一个负数,则返回-1
*/
public int getArea(int length, int width) {
if (length < 0 || width < 0) {
return -1;
}
return length * width;
}
}
7、@throws 与 @exception
@throws 标签用于描述方法的异常情况。其语法如下:
@throws 异常名称 异常描述
在此,通过异常名称指定异常的完整限定名称,而异常描述是一个描述异常可能发生的字符串。@throws 标签只能用于方法或构造方法的文档注释中。
@exception 标签与 @throws 标签具有相同的含义和用法,但目前 @throws 已成为更常用的形式。
/**
* 用于演示@throws的用法
*
* @author 老谭
*/
public class ThrowsTag {
/**
* 计算正方形的面积
*
* @param size 边长
* @return 正方形的面积
* @throws Exception 边长为负数时抛出异常
*/
public int getArea(int size) throws Exception {
if (size < 0) {
throw new Exception("边长不能为负数");
}
return size * size;
}
}
8、@serial
javadoc 工具会生成一个文件名为 “serialized-form.html” 页面,其中包含了所有序列化类的所有相关信息。该工具会为序列化类创建一个 “See Also” 部分,其中包含指向 “serialized-form.html” 页面的链接。
只有实现了java.io.Serializable 或 java.io.Externalizable 接口的类才会被加到 “serialized-form.html” 页面中。
@serial 标签用于为类的默认可序列化字段添加描述信息。所指定的描述内容将会被添加到该字段的 “serialized-form.html” 页面中。以下是一个使用 @serial标签对字段进行操作的示例:
@serial 描述
还可以通过使用 @serial 标签中的 include 或 exclude 参数来决定某个包或类是否出现在 “serialized-form.html” 页面中。如果在包级别和类级别都使用了 @serial 标签,那么类级别的标签将具有优先级。默认情况下,如果一个可序列化的类是公共或受保护的,它就会被包含在 “serialized-form.html” 页面中。以下的文档注释将 User 类排除在"serialized-form.html" 页面之外:
/**
* 演示@serial的用法
*
* @author 老谭
* @serial exclude
*/
public class SerialTag implements Serializable{
/**
* @serial 用户姓名
*/
private String name;
}
9、@serialData
实现 java.io.Externalizable 接口的类需要实现 readExternal() 和 writeExternal() 方法。实现可序列化的类还可以实现 writeObject()、readObject()、writeReplace() 和 readResolve() 方法,以自定义该类对象的序列化过程。
@serialData 标签可与这六种方法中的任何一种的文档注释一同使用。这些数据描述文本应当描述所采用的序列化形式中数据的类型及其排列顺序。
其语法结构如下:
@serialData 描述
示例如下:
/**
*
* @param s 对象输出流
* @serialData 保存加密后的name到流中
*/
private void writeObject(ObjectOutputStream s) {
// ......
}
10、@serialField
一个可序列化的类可以包含一个名为 “serialPersistentFields” 的字段,该字段是一个 ObjectStreamField 类型的数组。@serialField 标签用于描述该数组中的每个元素。这些元素的描述将会出现在 “serialized-form.html” 页面上。其语法如下:
@serialField 字段的名称 类型 描述
以下的文档注释使用了 @serialField 标签来记录 ObjectStreamField 的名称和高度这两个组成部分:
/**
* @serial 用户姓名
*/
private String name;
/**
* @serial 性别
*/
private double height;
/**
* @serialField name String 用户姓名
* @serialField height double 用户身高
*/
private static final ObjectStreamField[] serialPersistentFields
= {new ObjectStreamField("name", String.class),
new ObjectStreamField("height", double.class)
};
11、@provides 与 @uses
@provides 与 @uses只能用于模块声明中。
@provides标签用于描述一个模块所提供的服务。其语法如下:
@provides 类型 描述
类型用于指定服务提供商的类型,描述则提供了该服务提供商的情况,可选。
/**
* @provides com.laotan.base.List 该模块提供基础数据结构的实现
*/
module com.laotan {
exports com.laotan.base;
provides com.laotan.base.List with com.laotan.base.MyList;
}
@uses标签用于记录一个模块所依赖的服务提供者信息。其语法结构如下:
@uses 类型 描述
在这里,类型指定了服务提供者的类型,而描述则指明了所提供的服务,。
示例代码如下:
/**
* @uses com.laotan.base.List 使用List服务
*/
module com.laotan.util {
requires com.laotan.base;
uses com.laotan.base.List;
}
12、@hidden
@hidden 标签可将程序元素从生成的 API 文档中隐藏起来。例如,除非使用 javadoc 工具指定相关选项将私有成员包含在 Javadoc 中,否则某个类型的所有私有成员都不会出现在 Javadoc 中。使用 @hidden 标签可以隐藏程序元素,否则无法通过任何其他选项将其排除在外。
比如在创建测试类时,可以通过使用 @hidden 标签来隐藏该测试类在 Javadoc 中的显示,其使用方式如下:
@hidden
内联标签
1、{@code} 与 {@literal}
{@code} 标签允许将文本(例如一段代码片段)嵌入到注释中。随后,文本将以原始的代码字体形式显示出来,不会进行任何进一步的处理,例如 有HTML标签也不会渲染。其语法如下:
{@code 代码片段}
示例:
/**
* 返回的值不能 {@code Integer.MAX_VALUE}
* @return 数量
*/
public int size(){
return 0;
}
{@literal}标签允许将文本嵌入到注释中。该文本将按原样显示,不会进行任何进一步的处理,例如 HTML 渲染。其语法如下:
{@literal 描述}
在这里,描述部分就是嵌入其中的文本内容。
2、{@docRoot}
它会将生成文档的根目录的相对路径作为结果,用于链接的 URL 部分。
假设您有一个名为 "copyright.html"的文件,该文件位于生成文档的根目录下。如果您想在文档注释中包含指向 “copyright.html” 文件的链接,您可以这样做:
{@docRoot} 指定了当前文档所在目录的路径
/**
* 一个测试类,请访问<a href="{@docRoot}/copyright.html">Copyright</a>页面.
*/
public class DocRoot {
}
3、{@link} 与 {@linkplain}
{@link} 会插入一个带有指定标签的内联链接,该标签将作为链接的文本内容。此标签生成的链接与 @see 标签的某些形式所生成的链接类似。两者的主要区别在于,此标签是内联标签,而 @see 标签是块标签。其语法如下:
{@link 模块名/包名.类名#成员名 显示的文本}
以下的文档注释展示了如何使用此标签。使用以下标签将会创建一个文本为“add”的链接,该链接将指向 ArrayList类的 add() 方法的文档:
/**
* 实现增加,看查看 {@link java.util.ArrayList#add(Object) ArrayList的add方法}
*/
public void add() {
}
文本字段是可选的。如果不包含该字段,成员将显示为链接。请注意,如果存在模块名称,则它与包名称之间会用“/”分隔。例如,
{@link java.base/java.io.Writer#write}
定义了与 java.io 中 Writer 类的 write() 方法的关联关系,该模块为 java.base。
{@linkplain} 标签与 {@link} 类似,该链接以纯文本字体显示,而{@link} 以代码字体显示。
4、{@index}
{@index} 标签用于指定将被索引的内容,从而在使用搜索功能时能够被找到。其语法如下:
{ @index 关键词 描述 }
其中,关键词是要被索引的项目(可以是带引号的字符串),而 描述是可选的。因此,在以下的 @throws 标签中,{@index} 会使“IO异常”这一术语被添加到索引中:
@throws IOException 输入信息有误导致出现 {@index IO异常 导致程序执行产生严重失败}.
注意该词“IO异常”仍会作为描述的一部分显示出来。只是现在它也已被编入索引。如果包含可选的“使用说明”字段,那么该描述将会出现在索引和搜索框中,以表明该术语的使用方式。例如,{@索引 IO异常 导致程序执行产生严重失败} 将会在索引和搜索框中显示“导致程序执行产生严重失败”这一内容。
5、{@inheritDoc}
它会从最近的可继承类或可实现的接口中复制方法的文档注释内容。
请注意,要使此标签能够复制文档内容,该标签所在的方法必须重写其父类中的某个方法,或者实现接口中的某个方法。
此标签只能在方法文档注释的主要描述部分内使用,或者在方法的 @return、@param 和 @throws 标签的文本参数中使用。如果它出现在主要描述部分内,它将复制被重写方法的主要描述。如果它出现在其他标签的文本中,则它将复制被重写方法中该标签的文本。
如果一个方法在父类中重写某个方法或在接口中实现某个方法,那么 Javadoc 工具会自动复制主要描述、@return、@param 和 @throws 标签的文档内容,前提是这些标签的主要描述在被重写的方法中缺失。
public class SuperClass {
/**
* 计算两个整数之和
*
* @param num1 第一个整数
* @param num2 第二个整数
* @return 返回相加之后的和
*/
public int add(int num1, int num2) {
return num1 + num2;
}
}
子类如下
public class SubClass extends SuperClass {
/**
* {@inheritDoc}
*
* @param num1 第一个整数
* @param num2 第二个整数
* @return {@inheritDoc}
*/
@Override
public int add(int num1, int num2) {
return super.add(num1, num2);
}
}
从最终产生的文档来看,不加这个标签,子类的文档注释也是直接复制自父类的注释,只是多了个到父类文档个超衔接。
6、{@summary}
{@summary} 标签明确指定了用于该项目的摘要文本,是Java 10 引入的。它必须是该项目文档中的第一个标签。其语法结构如下:
{@summary 摘要说明}
在此,摘要说明会为标记的元素(如:方法)提供一个概要,该概要可以跨越多行。若未使用{@summary},则项目文档注释中的第一行将被用作摘要。
/**
* {@summary 这个方法的注释就是演示一下@summary。
* 这个方法具有以下两个特征:
* <ul>
* <li>没有任何参数</li>
* <li>实际上啥也没干</li>
* </ul>
* }
*/
public void summary() {
}
没有使用@summary
/**
* 这个方法的注释就是演示一下@summary。
* 这个方法具有以下两个特征:
* <ul>
* <li>没有任何参数</li>
* <li>实际上啥也没干</li>
* </ul>
*/
public void withoutSummary() {
}
在最终产生的文档中,摘要的内容稍有不同。没有使用@summary的摘要只会显示一行,而使用了@summary的摘要显示比较完整。

7、{@systemProperty}
{@systemProperty} 标签用于指示系统属性,Java 12引入。其基本形式如下:
{@systemProperty 属性名}
示例:
{@systemProperty user.dir}
8、{@value}
{@value} 有两种形式。第一种形式会显示其前面常量的值,而该常量必须是一个静态字段。其形式如下:
{@value}
第二种形式用于显示指定静态字段的值。其形式如下:
{@value 包.类#成员}
如果使用的是本类的常量,可以省略#前面的限定。
示例如下:
public class ValueTag {
/**
* NUMBER1的值是{@value}
*/
public static final int NUMBER1 = 1;
/**
* NUMBER1的值是 {@value #NUMBER1}.
* NUMBER2的值是 {@value}.
*/
public final static int NUMBER2 = 2;
}
四、生成JavaDoc文档
1、使用javadoc命令行工具
JDK自带的javadoc工具可以产生JavaDoc文档,它需要在命令行运行。用法:
javadoc [options] [packagenames] [sourcefiles] [@files]
options选项非常多,这里列出几个:
| 选项 | 描述 |
|---|---|
| -public | 仅显示 public 类和成员 |
| -protected | 显示 protected/public 类和成员 (缺省) |
| -package | 显示 package/protected/public 类和成员 |
| -private | 显示所有类和成员 |
| -d | 指定输出文件的目标目录 |
| -version | 包含 @version 段 |
| -author | 包含 @author 段 |
| -windowtitle
| 文档的浏览器窗口标题 |
实例,在存放java文件的目录下在命令行窗口输出:
javadoc com.laotan -d docs -windowtitle 文档首页
产生的HTML文档会保存在docs目录下,可以直接双击首页 index.html。
2、使用IDEA提供的菜单



五、总结
本文介绍了Java文档注释中支持的各种标签及使用方式。
4299

被折叠的 条评论
为什么被折叠?



