# 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 推薦讀物