最近帮同学看毕设的时候,有一些同学写的是Spring,别说代码内注释了,就连Javadoc注释都没有,给我看的一阵头大,也感慨于学校居然什么都不教,大家连Javadoc是什么都不知道,让我很是难受。

Javadoc是Java官方推出的一个文档生成器,我以前在工作室讲Java基础的时候讲到Java 8以后不提供JRE的时候就提到过JDK里面有一个部分叫Javadoc,讲义应该在我的GitLab(讲纲1-2.1)上还能找到。

这个文档生成器会对开发者进行的标准多行注释进行解析,生成文档。因此我们在程序编写的时候对各种方法,类等进行标准Javadoc注释后就可以将他们生成类似于Java官方的API文档,至于文档有什么用应该就不需要我多说了。

代码编写

如果想生成文档,我们在写代码的时候只要在指定的方法上面按照以下的规范进行添加就可以了。

注释规范

首先,我们要明确Java的三种注释形式,分为单行注释与多行注释,而多行注释中只有下面第三条才满足生成Javadoc。

// 单行注释
/* 多行注释 */
/** 多行注释起始使用两个星号,为Javadoc格式 */

Javadoc的标准注释格式为,第一行是对方法的简单描述,第二行(可以写多行段落)是对方法的详细描述,第三行及之后是注释标签。需要注意的是,描述支持使用HTML标签,一般在段落前使用<p>标签,换行使用<br>标签,可以不写对应的闭合标签。当然,不写HTML标签也是可以的,但是一般要将段落通过标签标注。

在描述之后,可以空一行然后对对应的注释标签进行编写,一般,无论是类还是方法,都需要有作者标签,按照不同公司或项目的要求,也要打上相关时间或版本标签。此处的标签具体内容请参考下一节的标签表。

/**
 * 测试类。
 * <p>这是一个用于进行测试的测试类。
 *
 * @author UtopiaXC
 * @since  2022-05-13 11:06:12
 * @version 1.0
 */
public class Test {

}

同样的,除了类,方法也可以用相同的方式进行标注,不过需要注意,并不是所有标签都支持类、方法和变量,所以在对标签进行编写的时候,我们需要按照标签表的适用范围进行使用,同时,也要按照项目组相关规定进行编写。

在这里,可以发现,@param和@return标签后不仅有其变量名或类型,还有对其的描述。一般,在返回值的描述可以写在方法描述中,但是参数描述必须写在@param标签后面,需要用空格隔开变量名。

/**
 * 测试方法.
 * <p>这个方法是用来进行测试使用的<br>
 * 这是测试方法的第二行
 *
 * @author UtopiaXC
 * @since  2022-05-13 09:53:28
 * @param a 字符串参数
 * @param b 整型参数
 * @return int 返回一个整型量123
 */
public int test(String a,int b){
    return 123;
}

除了类(包括接口与枚举)和方法,成员变量也需要进行注释。

/**
 * 测试变量
 */
private String test;

/**
 * 这是两个测试变量,不要这样进行定义,这不符合规范
 */
private String test1,test2;

最后,我们将所有这些整合起来,就是这样的效果。

/**
 * 测试类。
 * <p>这是一个用于进行测试的测试类。
 *
 * @author UtopiaXC
 * @since  2022-05-13 11:06:12
 * @version 1.0
 */
public class Test {

    /**
     * 测试变量
     */
    private String test;

    /**
     * 测试构造函数。
     * <p>这是一个用于初始化测试类的构造函数
     *
     * @author UtopiaXC
     * @since  2022-05-13 11:08:10
     */
    public Test() {
    }

    /**
     * 测试方法。
     * <p>这个方法是用来进行测试使用的<br>
     * 这是测试方法的第二行
     *
     * @author UtopiaXC
     * @since  2022-05-13 09:53:28
     * @param a 字符串参数
     * @param b 整型参数
     * @return int 返回一个整型量123
     */
    public int test(String a,int b){
        return 123;
    }

    /**
     * 测试枚举。
     * <p>这是一个用于测试的枚举类
     *
     * @author UtopiaXC
     * @since 2022-05-13 11:39:59
     */
    public enum TestEnums{
        /**
         * 请求成功
         */
        SUCCESS(200,"Success"),
        /**
         * 资源不存在
         */
        NOT_FOUND(404,"Not Found");

        /**
         * HTTP代码
         */
        private final int code;
        /**
         * 描述
         */
        private final String description;

        /**
         * 构造方法
         * <p>用于初始化枚举类
         *
         * @author UtopiaXC
         * @since 2022-05-13 11:43:51
         * @param code HTTP代码
         * @param description 描述
         */
        TestEnums(int code, String description) {
            this.code = code;
            this.description = description;
        }

        /**
         * 获取HTTP代码
         * <p>返回枚举的HTTP代码
         *
         * @author UtopiaXC
         * @since 2022-05-13 11:44:26
         * @return int HTTP代码
         */
        public int getCode() {
            return code;
        }

        /**
         * 获取描述
         * <p>返回枚举的描述
         *
         * @author UtopiaXC
         * @since 2022-05-13 11:44:26
         * @return java.lang.String 描述
         */
        public String getDescription() {
            return description;
        }
    }

    /**
     * 测试接口
     * <p>这是一个用来测试的接口
     *
     * @author UtopiaXC
     * @since 2022-05-13 11:48:24
     */
    interface testInterface{

    }
}

标签表

以下列出常用的标签,信息来自维基百科。需要注意的是,有一些标签需要被括在大括号中,使用时不要省略。

标签&参数 用途 适用于 引入版本
@author John Smith 描述作者。 类、接口、枚举
{@docRoot} 表示从任何生成的页面生成的文档的根目录的相对路径。 类、接口、枚举、成员、方法
@version 版本 提供软件版本,每个类或接口最多一个。 类、接口、枚举
@since 起始 描述此功能首次存在的时间。 类、接口、枚举、成员、方法
@see 参考 提供指向其他文档元素的链接。 类、接口、枚举、成员、方法
@param 名称 描述 描述方法的一个参数。 方法
@return 描述 描述返回值。 方法
@exception 类 描述 @throws 类 描述 描述可能从此方法抛出的异常。 方法
@deprecated 描述 描述一个过时的方法。 类、接口、枚举、成员、方法
{@inheritDoc} 从被覆盖的方法复制描述。 覆盖方法 1.4.0
{@link 参考} 链接到其他符号。 类、接口、枚举、成员、方法
{@linkplain 参考} 与{@link}相同,但链接的标签以纯文本显示,而不是代码字体。 类、接口、枚举、成员、方法
{@value #STATIC_FIELD} 返回静态成员的值。 静态成员 1.4.0
{@code 文本} 在代码字体中格式化文字文本,等同于<code> {@literal} </code> 。 类、接口、枚举、成员、方法 1.5.0
{@literal 文本} 表示文本,随附的文本被解释为不包含HTML标记或嵌套的javadoc标记。 类、接口、枚举、成员、方法 1.5.0
{@serial 文本} 在Javadoc注释中用于默认的可序列化字段。 成员
{@serialData 文本} 记录writeObject()或writeExternal()方法写入的数据。 成员、方法
{@serialField 文本} 记录ObjectStreamField组件。 成员

生成文档

现在,我们结束了代码编写,直接使用javadoc就可以生成文档了。

其中,-d参数为输出路径,-windowtitle参数为浏览器标签标题,-doctitle为文档标题,-header是页面标题,最后,将我们要生成文档的文件添加到这里。

javadoc -d path -windowtitle title -doctitle test -header test Test.java

当然,如果你想生成整个项目或者指定的包,最后的Test.java可以改成对应的包名,不过要注意,需要要在顶级包的上级目录执行这条命令,不然会找不到类。

javadoc -d path -windowtitle title -doctitle test -header test com.example

然后,javadoc是无法映射GBK编码的,因此需要将其运行参数设置为UTF-8编码,不然我们代码中含有中文是无法进行识别的。

javadoc -encoding UTF-8 -charset UTF-8 -d path -windowtitle title -doctitle test -header test com.example

最后,我们访问生成目录的index.html就能看到相关的文档了。

1652415710993.png

文档首页

Idea

上面自己手动添加注释和生成文档的过程还是过于繁琐了,不过我们现在都用IDE开发程序,那就要好好利用。目前最主流的IDE还是Idea,如果你用Eclipse的话当我没说。这里介绍一下怎么在Idea里添加代码补全和自动生成文档。

自动补全

首先,我们打开设置,找到Editor,在Editor中我们能看到一个File and Code Templates和一个Live Templates。这里File and Code Templates是在创建文件的时候自动生成的代码,比如创建文件的时候打上时间,这个和javadoc无关,但是我也建议大家来设置一下。Live Templates则是脚本模板,我们可以编写脚本来自动生成注释。

这里要提一嘴,升级到2022版本后它疯狂让你装本地化,说实话我真的用不惯中文的IDE,因为学的时候就没有中文,所有教程全是英文的,用惯了你现在让我换成中文,要我老命,之前试了一下,本来一下子就能找到的东西换成中文彻底看不懂了。再加上其实这玩意儿的单词全是基础词汇,英语不好的人用惯了也能看懂的,所以我是不建议把开发工具换成中文的,作为程序员,英语能力很重要。

1652416085772.png

Editor设置页面

然后,我们点开Live Templates,在右边找到加号,点一下加号可以看到两个选项,我们先添加一个自定义的模板组,这里名字设置成Custom就可以。

1652416185946.png

我们选中创建好的模板组,再点击加号,选择添加一个动态脚本,Live Template。

1652416258195.png

这时候我们就能看到这个界面了。

1652416309546.png

然后,我们对模板进行设置。我们需要先修改以下四个框框的内容。

首先是左上角框框,里面填写上模板检测条件,因为我们是注释,所以这里填写注释头就可以。这里我填写的是“*”,至于为什么不填写“/**”,是因为后面有一个groove脚本,不知道为什么实测“/**”是无法被识别的。

然后是左面中间的框框,这里填写上我们要自动生成的内容。因为并不是所有的方法都有相同的标签,因此这里我选择了大部分通用的,如果多了就删,少了就加。这里要注意,$xxx$是变量,我们后面还要对这个进行设置。

*
 * 
 * <p>
 *
 * @author $user$
 * @since $data$ $time$
$param$ 
 * @return $return$
 */

左下角的框框是模板的适用范围,大家可以选择仅Java文件生效,但是其实全部文件生效也没什么问题。

最后是右边的框框,这个代表着自动补全响应事件。Enter是回车,意思是你输入了*之后敲回车,他就自动补全了,你可以根据自己需求设置,比如Tab之类的。

1652416388115.png

现在,是最关键的一步,我们需要对上面的变量进行赋值,不然生成的东西全是空的。这时我们点击这个按钮,会弹出一个框,这个框中只会有我们刚才定义的变量。

1652416834531.png

这里我放出我的变量设置,大家可以根据自己需求自己更改。这里需要注意的是,因为一般一个方法可能有多个参数,所以param是一个groove脚本。

user -> user()
data -> date("yyyy-MM-dd")
time -> time("HH:mm:ss")
param -> groovyScript("def result=''; def params=\"${_1}\".replaceAll('[\\\\[|\\\\]|\\\\s]', '').split(',').toList(); for(i = 0; i < params.size(); i++) {result+=' * @param ' + params[i] + ((i < params.size() - 1) ? '\\n' : '')}; return result", methodParameters())
return -> methodReturnType()

1652416870217.png

最后,全部完成后我们一路点OK回到编辑器,在相关的方法或类上面输入“/**”,然后点击回车(或者你自己设置的键),就会自动生成对应的注释了,然后我们将其信息填充进去就可以了。

1652417128934.png

文档生成

现在,我们通过模板已经可以自动生成注释了,接下来我们就可以通过idea进行文档的生成而不使用命令行工具了。

在左上角工具栏找到Tools->Generate JavaDoc,点开之后会弹出来一个对话框,我们把基本信息填写进去就可以了。

按照下面图片从上到下的顺序,分别是生成文档的范围,可以选择整个项目或者指定的范围。

第二个是输出的目录,千万别直接输出到桌面或者其他有文件的目录,它输出的是整个HTML资源,文件非常多。

第三个是生成相关的信息,这里需要改的是,如果我们需要生成私有变量或私有类的注释文档,需要将可见等级改为private(不过这并不安全,不建议这么操作),然后是右边的tag,我们可以给他全选上。

第四个是附件参数,和上面用命令行的问题一样,我们需要给它改成UTF-8编码

-encoding UTF-8 -charset UTF-8

最后,我们点击Generate,就会通过javadoc生成文档到我们指定的目录了。

1652417260019.png

1652417518838.png

最后,我想说的是,JetBrains家的IDE其实都是通过idea魔改来的,所以Android Studio,CLion之类的也可以通过这种方式来添加动态注释,不过除了Java语言也没有javadoc就是了。

还有就是,学校教的东西其实都很短浅,希望大家保持对代码的兴趣,不断学习。

鸣谢与参考

[1] 维基百科.Javadoc

[2] IBM.Javadoc 生成

本篇内容为原创内容,采用CC BY-NC-SA 4.0协议许可
2022-05-13 13:04
UtopiaXC
于大连


尽管如此,世界依旧美丽