# 2.8 注释和嵌入文档
(2)8 注释和嵌入文档
Java里有两种类型的注释。第一种是传统的、C语言风格的注释,是从C++继承而来的。这些注释用一个 `/*` 起头,随后是注释内容,并可跨越多行,最后用一个`*/`结束。注意许多程序员在连续注释内容的每一行都用一个 `*` 开头,所以经常能看到象下面这样的内容:
```
/* 这是
* 一段注释,
* 它跨越了多个行
*/
```
但请记住,进行编译时,`/*`和`*/`之间的所有东西都会被忽略,所以上述注释与下面这段注释并没有什么不同:
```
/* 这是一段注释,
它跨越了多个行 */
```
第二种类型的注释也起源于C++。这种注释叫作“单行注释”,以一个 `//` 起头,表示这一行的所有内容都是注释。这种类型的注释更常用,因为它书写时更方便。没有必要在键盘上寻找 `/` ,再寻找 `*` (只需按同样的键两次),而且不必在注释结尾时加一个结束标记。下面便是这类注释的一个例子:
```
// 这是一条单行注释
```
## 2.8.1 注释文档
对于Java语言,最体贴的一项设计就是它并没有打算让人们为了写程序而写程序——人们也需要考虑程序的文档化问题。对于程序的文档化,最大的问题莫过于对文档的维护。若文档与代码分离,那么每次改变代码后都要改变文档,这无疑会变成相当麻烦的一件事情。解决的方法看起来似乎很简单:将代码同文档“链接”起来。为达到这个目的,最简单的方法是将所有内容都置于同一个文件。然而,为使一切都整齐划一,还必须使用一种特殊的注释语法,以便标记出特殊的文档;另外还需要一个工具,用于提取这些注释,并按有价值的形式将其展现出来。这些都是Java必须做到的。
用于提取注释的工具叫作`javadoc`。它采用了部分来自Java编译器的技术,查找我们置入程序的特殊注释标记。它不仅提取由这些标记指示的信息,也将毗邻注释的类名或方法名提取出来。这样一来,我们就可用最轻的工作量,生成十分专业的程序文档。
`javadoc`输出的是一个HTML文件,可用自己的Web浏览器查看。该工具允许我们创建和管理单个源文件,并生动生成有用的文档。由于有了`javadoc`,所以我们能够用标准的方法创建文档。而且由于它非常方便,所以我们能轻松获得所有Java库的文档。
## 2.8.2 具体语法
所有javadoc命令都只能出现于 `/**` 注释中。但和平常一样,注释结束于一个 `*/` 。主要通过两种方式来使用`javadoc`:嵌入的HTML,或使用“文档标记”。其中,“文档标记”(Doc tags)是一些以`@`开头的命令,置于注释行的起始处(但前导的`*`会被忽略)。
有三种类型的注释文档,它们对应于位于注释后面的元素:类、变量或者方法。也就是说,一个类注释正好位于一个类定义之前;变量注释正好位于变量定义之前;而一个方法定义正好位于一个方法定义的前面。如下面这个简单的例子所示:
```
/** 一个类注释 */
public class docTest {
/** 一个变量注释 */
public int i;
/** 一个方法注释 */
public void f() {}
}
```
注意`javadoc`只能为`public`(公共)和`protected`(受保护)成员处理注释文档。`private`(私有)和“友好”(详见5章)成员的注释会被忽略,我们看不到任何输出(也可以用`-private`标记包括`private`成员)。这样做是有道理的,因为只有`public`和`protected`成员才可在文件之外使用,这是客户程序员的希望。然而,所有类注释都会包含到输出结果里。
上述代码的输出是一个HTML文件,它与其他Java文档具有相同的标准格式。因此,用户会非常熟悉这种格式,可在您设计的类中方便地“漫游”。设计程序时,请务必考虑输入上述代码,用`javadoc`处理一下,观看最终HTML文件的效果如何。
## 2.8.3 嵌入HTML
`javadoc`将HTML命令传递给最终生成的HTML文档。这便使我们能够充分利用HTML的巨大威力。当然,我们的最终动机是格式化代码,不是为了哗众取宠。下面列出一个例子:
```
/**
* <pre>
* System.out.println(new Date());
* </pre>
*/
```
亦可象在其他Web文档里那样运用HTML,对普通文本进行格式化,使其更具条理、更加美观:
```
/**
* 您<em>甚至</em>可以插入一个列表:
* <ol>
* <li> 项目一
* <li> 项目二
* <li> 项目三
* </ol>
*/
```
注意在文档注释中,位于一行最开头的星号会被`javadoc`丢弃。同时丢弃的还有前导空格。`javadoc` 会对所有内容进行格式化,使其与标准的文档外观相符。不要将`<h1>`或`<hr>`这样的标题当作嵌入HTML使用,因为`javadoc`会插入自己的标题,我们给出的标题会与之冲撞。
所有类型的注释文档——类、变量和方法——都支持嵌入HTML。
## 2.8.4 `@see`:引用其他类
所有三种类型的注释文档都可包含`@see`标记,它允许我们引用其他类里的文档。对于这个标记,`javadoc`会生成相应的HTML,将其直接链接到其他文档。格式如下:
```
@see 类名
@see 完整类名
@see 完整类名#方法名
```
每一格式都会在生成的文档里自动加入一个超链接的“See Also”(参见)条目。注意`javadoc`不会检查我们指定的超链接,不会验证它们是否有效。
## 2.8.5 类文档标记
随同嵌入HTML和`@se`e引用,类文档还可以包括用于版本信息以及作者姓名的标记。类文档亦可用于“接口”目的(本书后面会详细解释)。
**1. `@version`**
格式如下:
```
@version 版本信息
```
其中,“版本信息”代表任何适合作为版本说明的资料。若在`javadoc`命令行使用了`-version`标记,就会从生成的HTML文档里提取出版本信息。
**2. `@author`**
格式如下:
```
@author 作者信息
```
其中,“作者信息”包括您的姓名、电子函件地址或者其他任何适宜的资料。若在`javadoc`命令行使用了`-author`标记,就会专门从生成的HTML文档里提取出作者信息。
可为一系列作者使用多个这样的标记,但它们必须连续放置。全部作者信息会一起存入最终HTML代码的单独一个段落里。
## 2.8.6 变量文档标记
变量文档只能包括嵌入的HTML以及`@see`引用。
## 2.8.7 方法文档标记
除嵌入HTML和`@see`引用之外,方法还允许使用针对参数、返回值以及异常的文档标记。
**1. `@param`**
格式如下:
```
@param 参数名 说明
```
其中,“参数名”是指参数列表内的标识符,而“说明”代表一些可延续到后续行内的说明文字。一旦遇到一个新文档标记,就认为前一个说明结束。可使用任意数量的说明,每个参数一个。
**2. `@return`**
格式如下:
```
@return 说明
```
其中,“说明”是指返回值的含义。它可延续到后面的行内。
**3. `@exception`**
有关“异常”(`Exception`)的详细情况,我们会在第9章讲述。简言之,它们是一些特殊的对象,若某个方法失败,就可将它们“扔出”对象。调用一个方法时,尽管只有一个异常对象出现,但一些特殊的方法也许能产生任意数量的、不同类型的异常。所有这些异常都需要说明。所以,异常标记的格式如下:
```
@exception 完整类名 说明
```
其中,“完整类名”明确指定了一个异常类的名字,它是在其他某个地方定义好的。而“说明”(同样可以延续到下面的行)告诉我们为什么这种特殊类型的异常会在方法调用中出现。
**4. `@deprecated`**
这是Java 1.1的新特性。该标记用于指出一些旧功能已由改进过的新功能取代。该标记的作用是建议用户不必再使用一种特定的功能,因为未来改版时可能摒弃这一功能。若将一个方法标记为`@deprecated`,则使用该方法时会收到编译器的警告。
## 2.8.8 文档示例
下面还是我们的第一个Java程序,只不过已加入了完整的文档注释:
92页程序
第一行:
```
//: Property.java
```
采用了我自己的方法:将一个`:`作为特殊的记号,指出这是包含了源文件名字的一个注释行。最后一行也用这样的一条注释结尾,它标志着源代码清单的结束。这样一来,可将代码从本书的正文中方便地提取出来,并用一个编译器检查。这方面的细节在第17章讲述。
- Java 编程思想
- 写在前面的话
- 引言
- 第1章 对象入门
- 1.1 抽象的进步
- 1.2 对象的接口
- 1.3 实现方案的隐藏
- 1.4 方案的重复使用
- 1.5 继承:重新使用接口
- 1.6 多态对象的互换使用
- 1.7 对象的创建和存在时间
- 1.8 异常控制:解决错误
- 1.9 多线程
- 1.10 永久性
- 1.11 Java和因特网
- 1.12 分析和设计
- 1.13 Java还是C++
- 第2章 一切都是对象
- 2.1 用引用操纵对象
- 2.2 所有对象都必须创建
- 2.3 绝对不要清除对象
- 2.4 新建数据类型:类
- 2.5 方法、参数和返回值
- 2.6 构建Java程序
- 2.7 我们的第一个Java程序
- 2.8 注释和嵌入文档
- 2.9 编码样式
- 2.10 总结
- 2.11 练习
- 第3章 控制程序流程
- 3.1 使用Java运算符
- 3.2 执行控制
- 3.3 总结
- 3.4 练习
- 第4章 初始化和清除
- 4.1 用构造器自动初始化
- 4.2 方法重载
- 4.3 清除:收尾和垃圾收集
- 4.4 成员初始化
- 4.5 数组初始化
- 4.6 总结
- 4.7 练习
- 第5章 隐藏实现过程
- 5.1 包:库单元
- 5.2 Java访问指示符
- 5.3 接口与实现
- 5.4 类访问
- 5.5 总结
- 5.6 练习
- 第6章 类复用
- 6.1 组合的语法
- 6.2 继承的语法
- 6.3 组合与继承的结合
- 6.4 到底选择组合还是继承
- 6.5 protected
- 6.6 累积开发
- 6.7 向上转换
- 6.8 final关键字
- 6.9 初始化和类装载
- 6.10 总结
- 6.11 练习
- 第7章 多态性
- 7.1 向上转换
- 7.2 深入理解
- 7.3 覆盖与重载
- 7.4 抽象类和方法
- 7.5 接口
- 7.6 内部类
- 7.7 构造器和多态性
- 7.8 通过继承进行设计
- 7.9 总结
- 7.10 练习
- 第8章 对象的容纳
- 8.1 数组
- 8.2 集合
- 8.3 枚举器(迭代器)
- 8.4 集合的类型
- 8.5 排序
- 8.6 通用集合库
- 8.7 新集合
- 8.8 总结
- 8.9 练习
- 第9章 异常差错控制
- 9.1 基本异常
- 9.2 异常的捕获
- 9.3 标准Java异常
- 9.4 创建自己的异常
- 9.5 异常的限制
- 9.6 用finally清除
- 9.7 构造器
- 9.8 异常匹配
- 9.9 总结
- 9.10 练习
- 第10章 Java IO系统
- 10.1 输入和输出
- 10.2 增添属性和有用的接口
- 10.3 本身的缺陷:RandomAccessFile
- 10.4 File类
- 10.5 IO流的典型应用
- 10.6 StreamTokenizer
- 10.7 Java 1.1的IO流
- 10.8 压缩
- 10.9 对象序列化
- 10.10 总结
- 10.11 练习
- 第11章 运行期类型识别
- 11.1 对RTTI的需要
- 11.2 RTTI语法
- 11.3 反射:运行期类信息
- 11.4 总结
- 11.5 练习
- 第12章 传递和返回对象
- 12.1 传递引用
- 12.2 制作本地副本
- 12.3 克隆的控制
- 12.4 只读类
- 12.5 总结
- 12.6 练习
- 第13章 创建窗口和程序片
- 13.1 为何要用AWT?
- 13.2 基本程序片
- 13.3 制作按钮
- 13.4 捕获事件
- 13.5 文本字段
- 13.6 文本区域
- 13.7 标签
- 13.8 复选框
- 13.9 单选钮
- 13.10 下拉列表
- 13.11 列表框
- 13.12 布局的控制
- 13.13 action的替代品
- 13.14 程序片的局限
- 13.15 视窗化应用
- 13.16 新型AWT
- 13.17 Java 1.1用户接口API
- 13.18 可视编程和Beans
- 13.19 Swing入门
- 13.20 总结
- 13.21 练习
- 第14章 多线程
- 14.1 反应灵敏的用户界面
- 14.2 共享有限的资源
- 14.3 堵塞
- 14.4 优先级
- 14.5 回顾runnable
- 14.6 总结
- 14.7 练习
- 第15章 网络编程
- 15.1 机器的标识
- 15.2 套接字
- 15.3 服务多个客户
- 15.4 数据报
- 15.5 一个Web应用
- 15.6 Java与CGI的沟通
- 15.7 用JDBC连接数据库
- 15.8 远程方法
- 15.9 总结
- 15.10 练习
- 第16章 设计模式
- 16.1 模式的概念
- 16.2 观察器模式
- 16.3 模拟垃圾回收站
- 16.4 改进设计
- 16.5 抽象的应用
- 16.6 多重分发
- 16.7 访问器模式
- 16.8 RTTI真的有害吗
- 16.9 总结
- 16.10 练习
- 第17章 项目
- 17.1 文字处理
- 17.2 方法查找工具
- 17.3 复杂性理论
- 17.4 总结
- 17.5 练习
- 附录A 使用非JAVA代码
- 附录B 对比C++和Java
- 附录C Java编程规则
- 附录D 性能
- 附录E 关于垃圾收集的一些话
- 附录F 推荐读物