阅读经典——《Effective Java》09
要想使一个API真正可用,就必须为其编写文档。Java提供了Javadoc工具,使得为API编写文档变得非常容易。Javadoc利用特殊格式的文档注释,根据源代码自动生成API文档。
- 通用规则
- 案例说明
- 更多用法
通用规则
- 必须在每个被导出的类、接口、构造器、方法和域声明之前增加一个文档注释。如果类是可序列化的,也应该对它的序列号形式编写文档。
-
方法的文档注释应该简洁地描述出它和客户端之间的约定。这个约定应该说明这个方法做了什么,而不是说明它是如何做的。文档注释应该列举出这个方法的所有前提条件和后置条件。所谓前提条件是指为了使客户能够调用这个方法而必须要满足的条件;所谓后置条件是指在调用成功完成之后,哪些条件必须要满足。一般情况下,前提条件由
@throws
标签描述隐含的异常,也可以在一些受影响参数的@param
标签中指定前提条件。除此之外,文档注释中还应该描述方法的副作用,所谓副作用是指方法执行后对系统状态的影响。例如,如果方法启动了后台线程,文档中就应该说明这一点。最后,文档注释也应该描述类或者方法的线程安全性。
案例说明
下面这个简短的文档注释演示了一些常见用法。
/**
* Returns the element at the specified position in this list.
*
* <p>This method is <i>not</i> guaranteed to run in constant
* time. In some implementations it may run in time proportional
* to the element position.
*
* @param index index of element to return; must be
* non-negative and less than the size of this list
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= this.size()})
*/
E get(int index);
- 文档注释必须以
/**
开头,否则Javadoc无法识别。 - 文档注释第一句话作为概要描述。概要描述必须独立地描述目标元素的功能,同一个类或接口中的任意两个成员或构造器,不应该具有相同的概要描述。即使是重载方法也不行。
- 每个参数都应该有一个
@param
标签,标签后面第一个单词为参数名称,接着是对该参数的解释和要求。 - 返回类型非
void
的方法都应该有一个@return
标签,描述返回值所表示的内容。 - 该方法可能抛出的每一个异常,无论是受检异常还是非受检异常,都要对应一个
@throws
标签。标签后面第一个单词为异常类型,接着是一句话,应该以if
开头,描述该异常将在什么情况下被抛出。@param
、@return
和@throws
都不以句点结束。 -
@code
标签可用于任何需要展示代码的地方,被该标签包围的内容会以特殊的字体显示,并且不对其中内容做任何HTML解析。 - 按惯例,单词“this”用在实例方法的文档注释中时,应该始终是指方法调用所在的对象。
- 可以用
@literal
标签展示包含HTML元字符的句子。它除了不改变显示样式外,其余效果和@code
一样。
更多用法
我们需要额外注意一下泛型、枚举和注解的文档注释。
- 泛型的文档注释应该说明所有类型参数。
/**
* An object that maps keys to values. A map cannot contain
* duplicate keys; each key can map to at most one value.
*
* (Remainder omitted)
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/
public interface Map<K, V> {
// Remainder omitted
}
- 当为枚举编写文档时,要确保在文档中说明常量。
/**
* An instrument section of a symphony orchestra.
*/
public enum OrchestraSection {
/** Woodwinds, such as flute, clarinet, and oboe. */
WOODWIND,
/** Brass instruments, such as french horn and trumpet. */
BRASS,
/** Percussion instruments, such as timpani and cymbals. */
PERCUSSION,
/** Stringed instruments, such as violin and cello. */
STRING;
}
- 为注解类型编写文档时,要确保在文档中说明所有成员,以及类型本身。使用动词短语说明当程序元素具有这种类型的注解时它表示什么意思。
/**
* Indicates that the annotated method is a test method that
* must throw the designated exception to succeed.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
/**
* The exception that the annotated test method must throw
* in order to pass. (The test is permitted to throw any
* subtype of the type described by this class object.)
*/
Class<? extends Exception> value();
}
另外,类是否是线程安全的,应该在文档中说明它的线程安全级别。如果类是可序列化的,就应该在文档中说明它的序列化形式。Javadoc具有继承方法注释的能力,如果API元素没有文档注释,Javadoc会自动搜索最适用的接口或超类的文档注释,并且接口优先于超类。
关注作者或文集《Effective Java》,第一时间获取最新发布文章。