目錄 前言 Java 的語法與 C++ 及為相似,,那么,,你知道 Java 的注釋有幾種嗎?是兩種,? // 注釋一行 不完全對(duì),,除了以上兩種之外,還有第三種,,文檔注釋: /** ...... */ 注釋若干行,,并寫入 javadoc 文檔 通常這種注釋的多行寫法如下: /** 暫停,暫停,!這第三種注釋有什么用,?javadoc 又是什么東西? 好,,那就讓我告訴你—— Java 程序員都應(yīng)該知道使用 JDK 開發(fā),,最好的幫助信息就來自 SUN 發(fā)布的 Java 文檔。它分包,、分類詳細(xì)的提供了各方法,、屬性的幫助信息,具有詳細(xì)的類樹信息,、索引信息等,,并提供了許多相關(guān)類之間的關(guān)系,,如繼承、實(shí)現(xiàn)接口,、引用等,。 Java 文檔全是由一些 html 文件組織起來的,在 SUM 的站點(diǎn)上可以下載它們的壓縮包,。但是你肯定想不到,這些文檔我們可以自己生成,?!痛舜蜃。俚跻淮挝缚?。 安裝了 JDK 之后,,安裝目錄下有一個(gè) src.jar 文件或者 src.zip 文件,它們都是以 ZIP 格式壓縮的,,可以使用 WinZip 解壓,。解壓之后,我們就可以看到分目錄放的全是 .java 文件,。是了,,這些就是 Java 運(yùn)行類的源碼了,非常完整,,連注釋都寫得一清二楚……不過,,怎么看這些注釋都有點(diǎn)似曾相識(shí)的感覺? 這就不奇怪了,,我們的迷底也快要揭開了,。如果你仔細(xì)對(duì)比一下 .java 源文件中的文檔注釋 (/** ... */) 和 Java 文檔的內(nèi)容,你會(huì)發(fā)現(xiàn)它們就是一樣的,。Java 文檔只是還在格式和排版上下了些功夫,。再仔細(xì)一點(diǎn),你會(huì)發(fā)現(xiàn) .java 源文件中的注釋還帶有 HTML 標(biāo)識(shí),,如 <B>,、<BR>、<Code> 等,,在 Java 文檔中,,該出現(xiàn)這些標(biāo)識(shí)的地方,已經(jīng)按標(biāo)識(shí)的的定義進(jìn)行了排版,。 終于真像大白了,,原來 Java 文檔是來自這些注釋。難怪這些注釋叫做文檔注釋呢,!不過,,是什么工具把這些注釋變成文檔的呢,? 是該請(qǐng)出 javadoc 的時(shí)候了。在 JDK 的 bin 目錄下你可以找到 javadoc,,如果是 Windows 下的 JDK,,它的文件名為 javadoc.exe。使用 javdoc 編譯 .java 源文件時(shí),,它會(huì)讀出 .java 源文件中的文檔注釋,,并按照一定的規(guī)則與 Java 源程序一起進(jìn)行編譯,生成文檔,。 介紹 javadoc 的編譯命令之前,,還是先了解一下文檔注釋的格式吧。不過為了能夠編譯下面提到的若干例子,,這里先介紹一條 javadoc 命令: javadoc -d 文檔存放目錄 -author -version 源文件名.java 這條命令編譯一個(gè)名為 “源文件名.java”的 java 源文件,,并將生成的文檔存放在“文檔存放目錄”指定的目錄下,生成的文檔中 index.html 就是文檔的首頁,。-author 和 -version 兩個(gè)選項(xiàng)可以省略,。 文檔注釋可以用于對(duì)類、屬性,、方法等進(jìn)行說明,。寫文檔注釋時(shí)除了需要使用 /** .... */ 限定之外,還需要注意注釋內(nèi)部的一些細(xì)節(jié)問題,。 生成的文檔是 HTML 格式,,而這些 HTML 格式的標(biāo)識(shí)符并不是 javadoc 加的,而是我們?cè)趯懽⑨尩臅r(shí)候?qū)懮先サ?。比如,,需要換行時(shí),不是敲入一個(gè)回車符,,而是寫入 <br>,,如果要分段,就應(yīng)該在段前寫入 <p>,。 因此,,格式化文檔,就是在文檔注釋中添加相應(yīng)的 HTML 標(biāo)識(shí),。 文檔注釋的正文并不是直接復(fù)制到輸出文件 (文檔的 HTML 文件),,而是讀取每一行后,刪掉前導(dǎo)的 * 號(hào)及 * 號(hào)以前的空格,,再輸入到文檔的,。如
編譯輸出后的 HTML 源碼則是
前導(dǎo)的 * 號(hào)允許連續(xù)使用多個(gè),其效果和使用一個(gè) * 號(hào)一樣,,但多個(gè) * 號(hào)前不能有其它字符分隔,,否則分隔符及后面的 * 號(hào)都將作為文檔的內(nèi)容,。* 號(hào)在這里是作為左邊界使用,如上例的第一行和第二行,;如果沒有前導(dǎo)的 * 號(hào),,則邊界從第一個(gè)有效字符開始,而不包括前面的空格,,如上例第三行,。 還有一點(diǎn)需要說明,文檔注釋只說明緊接其后的類,、屬性或者方法,。如下例:
上例中的三處注釋就是分別對(duì)類、屬性和方法的文檔注釋,。它們生成的文檔分別是說明緊接其后的類,、屬性,、方法的,。“緊接”二字尤其重要,,如果忽略了這一點(diǎn),,就很可能造成生成的文檔錯(cuò)誤。如
這個(gè)文檔注釋將生成正確的文檔,。但只需要改變其中兩行的位置,,變成下例,就會(huì)出錯(cuò):
這個(gè)例子只把上例的 import 語句和文檔注釋部分交換了位置,,結(jié)果卻大不相同——生成的文檔中根本就找不到上述注釋的內(nèi)容了,。原因何在? “/** commnet for class */”是對(duì) class Test 的說明,,把它放在“public class Test { ...... }”之前時(shí),,其后緊接著 class Test,符合規(guī)則,,所以生成的文檔正確,。但是把它和“import java.lang.*;”調(diào)換了位置后,其后緊接的就是不 class Test 了,,而是一個(gè) import 語句,。由于文檔注釋只能說明類、屬性和方法,,import 語句不在此列,,所以這個(gè)文檔注釋就被當(dāng)作錯(cuò)誤說明省略掉了。 根據(jù)在文檔中顯示的效果,,文檔注釋分為三部分,。先舉例如下,,以便說明。
第一部分是簡(jiǎn)述,。文檔中,對(duì)于屬性和方法都是先有一個(gè)列表,,然后才在后面一個(gè)一個(gè)的詳細(xì)的說明,。列表中屬性名或者方法名后面那段說明就是簡(jiǎn)述。如下圖中被紅框框選的部分: 簡(jiǎn)述部分寫在一段文檔注釋的最前面,,第一個(gè)點(diǎn)號(hào) (.) 之前 (包括點(diǎn)號(hào)),。換句話說,就是用第一個(gè)點(diǎn)號(hào)分隔文檔注釋,,之前是簡(jiǎn)述,,之后是第二部分和第三部分。如上例中的 “* show 方法的簡(jiǎn)述.”,。 有時(shí),,即使正確地以一個(gè)點(diǎn)號(hào)作為分隔,javadoc 仍然會(huì)出錯(cuò),,把點(diǎn)號(hào)后面的部分也做為了第一部分,。為了解決這個(gè)問題,我們可以使用一個(gè) <p> 標(biāo)志將第二分部分開為下一段,,如上例的“* <p>show 方法的詳細(xì)說明第一行 ....”,。除此之外,我們也可以使用 <br> 來分隔,。 第二部分是詳細(xì)說明部分,。該部分對(duì)屬性或者方法進(jìn)行詳細(xì)的說明,在格式上沒有什么特殊的要求,,可以包含若干個(gè)點(diǎn)號(hào),。它在文檔中的位置如下圖所示:
這部分文檔在上例中相應(yīng)的代碼是: * show 方法的簡(jiǎn)述. 發(fā)現(xiàn)什么了?對(duì)了,,簡(jiǎn)述也在其中,。這一點(diǎn)要記住了,不要畫蛇添足——在詳細(xì)說明部分中再寫一次簡(jiǎn)述哦,! 第三部分是特殊說明部分,。這部分包括版本說明、參數(shù)說明,、返回值說明等,。它在文檔中的位置: 第三部分在上例中相應(yīng)的代碼是 * @param b true 表示顯示,false 表示隱藏 除了 @param 和 @return 之外,還有其它的一些特殊標(biāo)記,,分別用于對(duì)類,、屬性和方法的說明……不要推我,我馬上就說,。 javadoc 標(biāo)記是插入文檔注釋中的特殊標(biāo)記,,它們用于標(biāo)識(shí)代碼中的特殊引用。javadoc 標(biāo)記由“@”及其后所跟的標(biāo)記類型和專用注釋引用組成,。記住了,,三個(gè)部分——@、標(biāo)記類型,、專用注釋引用,。不過我寧愿把它分成兩部分:@ 和標(biāo)記類型、專用注釋引用,。雖然 @ 和 標(biāo)記類型之間有時(shí)可以用空格符分隔,,但是我寧愿始終將它們緊挨著寫,以減少出錯(cuò)機(jī)會(huì),。 javadoc 標(biāo)記有如下一些:
下面詳細(xì)說明各標(biāo)記,。 @see 的句法有三種: @see 類名 類名,,可以根據(jù)需要只寫出類名 (如 String) 或者寫出類全名 (如 java.lang.String),。那么什么時(shí)候只需要寫出類名,什么時(shí)候需要寫出類全名呢,? 如果 java 源文件中的 import 語句包含了的類,,可以只寫出類名,如果沒有包含,,則需要寫出類全名,。java.lang 也已經(jīng)默認(rèn)被包含了。這和 javac 編譯 java 源文件時(shí)的規(guī)定一樣,,所以可以簡(jiǎn)單的用 javac 編譯來判斷,,源程序中 javac 能找到的類,javadoc 也一定能找到,;javac 找不到的類,,javadoc 也找不到,這就需要使用類全名了,。 方法名或者屬性名,,如果是屬性名,則只需要寫出屬性名即可;如果是方法名,,則需要寫出方法名以及參數(shù)類型,,沒有參數(shù)的方法,需要寫出一對(duì)括號(hào),。如
有時(shí)也可以偷懶:假如上例中,,沒有 count 這一屬性,那么參考方法 count() 就可以簡(jiǎn)寫成 @see count,。不過,,為了安全起見,還是寫全 @see count() 比較好,。 @see 的第二個(gè)句法和第三個(gè)句法都是轉(zhuǎn)向方法或者屬性的參考,,它們有什么區(qū)別呢? 第二個(gè)句法中沒有指出類名,,則默認(rèn)為當(dāng)前類,。所以它定義的參考,都轉(zhuǎn)向本類中的屬性或者方法,。而第三個(gè)句法中指出了類名,,則還可以轉(zhuǎn)向其它類的屬性或者方法。 關(guān)于 @see 標(biāo)記,,我們舉個(gè)例說明,。由于 @see 在對(duì)類說明、對(duì)屬性說明,、對(duì)方法說明時(shí)用法都一樣,,所以這里只以對(duì)類說明為例。
生成的文檔的相關(guān)部分如下圖: String 和 StringBuffer 都是在 java.lang 包中,,由于這個(gè)包是默認(rèn)導(dǎo)入了的,,所以這兩個(gè)類可以直接寫類名,也可以寫類全名,。str,、str() 為同名屬性和方法,所以方法名需要用 () 區(qū)分,。main 是帶參數(shù)的方法,,所以在 () 中指明了參數(shù)類型。toString() 雖然在本類中也有 (從 Object 繼承的),,但我們是想?yún)⒖?Object 類的 toString() 方法,,所以使用了 Object#toString()。 奇怪的是,,為什么其中只有 str,、str() 和 main(String[]) 變成了鏈接呢?那是因?yàn)榫幾g時(shí)沒有把 java.lang 包或者 Stirng、StringBuffer,、Object 三個(gè)類的源文件一起加入編譯,,所以,生成的文檔沒有關(guān)于那三個(gè)類的信息,,也就不可以建立鏈接了,。后面講解 javadoc 編譯命令的時(shí)候還會(huì)詳細(xì)說明。 上例中如果去把類中的 str 屬性去掉,,那么生成的文檔又會(huì)有什么變化呢,?你會(huì)發(fā)現(xiàn),原來是 str, str(),,而現(xiàn)在變成了 str(), str(),,因?yàn)?str 屬性已經(jīng)沒有了,所以 str 也表示方法 str(),。 這兩個(gè)標(biāo)記分別用于指明類的作者和版本。缺省情況下 javadoc 將其忽略,,但命令行開關(guān) -author 和 -version 可以修改這個(gè)功能,,使其包含的信息被輸出。這兩個(gè)標(biāo)記的句法如下: @author 作者名 其中,,@author 可以多次使用,,以指明多個(gè)作者,生成的文檔中每個(gè)作者之間使用逗號(hào) (,) 隔開,。@version 也可以使用多次,,只有第一次有效,生成的文檔中只會(huì)顯示第一次使用 @version 指明的版本號(hào),。如下例
生成文檔的相關(guān)部分如圖: 從生成文檔的圖示中可以看出,,兩個(gè) @author 語句都被編譯,,在文檔中生成了作者列表,。而兩個(gè) @version 語句中只有第一句被編譯了,只生成了一個(gè)版本號(hào),。 從圖上看,,作者列表是以逗號(hào)分隔的,如果我想分行顯示怎么辦,?另外,,如果我想顯示兩個(gè)以上的版本號(hào)又該怎么辦? ——我們可以將上述兩條 @author 語句合為一句,,把兩個(gè) @version 語句也合為一句: @author Fancy<br>Bird 結(jié)果如圖: 我們這樣做即達(dá)到了目的,,又沒有破壞規(guī)則。@author 之后的作者名和 @version 之后的版本號(hào)都可以是用戶自己定義的任何 HTML 格式,所以我們可以使用 <br> 標(biāo)記將其分行顯示,。同時(shí),,在一個(gè) @version 中指明兩個(gè)用 <br> 分隔的版本號(hào),也沒有破壞只顯示第一個(gè) @version 內(nèi)容的規(guī)則,。 3. 使用 @param,、@return 和 @exception 說明方法 這三個(gè)標(biāo)記都是只用于方法的。@param 描述方法的參數(shù),,@return 描述方法的返回值,,@exception 描述方法可能拋出的異常。它們的句法如下: @param 參數(shù)名 參數(shù)說明 每一個(gè) @param 只能描述方法的一個(gè)參數(shù),,所以,,如果方法需要多個(gè)參數(shù),就需要多次使用 @param 來描述,。 一個(gè)方法中只能用一個(gè) @return,,如果文檔說明中列了多個(gè) @return,則 javadoc 編譯時(shí)會(huì)發(fā)出警告,,且只有第一個(gè) @return 在生成的文檔中有效,。 方法可能拋出的異常應(yīng)當(dāng)用 @exception 描述。由于一個(gè)方法可能拋出多個(gè)異常,,所以可以有多個(gè) @exception,。每個(gè) @exception 后面應(yīng)有簡(jiǎn)述的異常類名,說明中應(yīng)指出拋出異常的原因,。需要注意的是,,異常類名應(yīng)該根據(jù)源文件的 import 語句確定是寫出類名還是類全名。 示例如下:
使用 javadoc 編譯生成的文檔相關(guān)部分如下圖: 可以看到,,上例中 @param b excrescent parameter 一句是多余的,,因?yàn)閰?shù)只是一個(gè) n,并沒有一個(gè) b但是 javadoc 編譯時(shí)并沒有檢查,。因此,,寫文檔注釋時(shí)一定要正確匹配參數(shù)表與方法中正式參數(shù)表的項(xiàng)目。如果方法參數(shù)表中的參數(shù)是 a,,文檔中卻給出對(duì)參數(shù) x 的解釋,,或者再多出一個(gè)參數(shù) i,就會(huì)讓人摸不著頭腦了,。@exceptin 也是一樣,。 上例程序中并沒有拋出一個(gè) NullPointerException,但是文檔注釋中為什么要寫上這么一句呢,,難道又是為了演示,?這不是為了演示描述多余的異常也能通過編譯,,而是為了說明寫異常說明時(shí)應(yīng)考運(yùn)行時(shí) (RunTime) 異常的可能性。上例程序中,,如果參數(shù) n 是給的一個(gè)空值 (null),,那么程序會(huì)在運(yùn)行的時(shí)候拋出一個(gè) NullPointerException,因此,,在文檔注釋中添加了對(duì) NullPointerException 的說明,。 上例中的 @return 語句有兩個(gè),但是根據(jù)規(guī)則,,同一個(gè)方法中,,只有第一個(gè) @return 有效,其余的會(huì)被 javadoc 忽略,。所以生成的文檔中沒有出現(xiàn)第二個(gè) @return 的描述,。 講到這里,該怎么寫文檔注釋你應(yīng)該已經(jīng)清楚了,,下面就開始講解 javadoc 的常用命令,。 運(yùn)行 javadoc -help 可以看到 javadoc 的用法,這里列舉常用參數(shù)如下: 用法: 選項(xiàng):
javadoc 編譯文檔時(shí)可以給定包列表,,也可以給出源程序文件列表,。例如在 CLASSPATH 下有兩個(gè)包若干類如下: fancy.Editor 這里有兩個(gè)包 (fancy 和 fancy.editor) 和 5 個(gè)類。那么編譯時(shí) (Windows 環(huán)境) 可以使用如下 javadoc 命令: javadoc fancy\Test.java fancy\Editor.java fancy\editor\ECommand.java fancy\editor\EDocument.java fancy\editor\EView.java 這是給出 java 源文件作為編譯參數(shù)的方法,,注意命令中指出的是文件路徑,,應(yīng)該根據(jù)實(shí)際情況改變。也可以是給出包名作為編譯參數(shù),,如: javadoc fancy fancy.editor 用瀏覽器打開生成文檔的 index.html 文件即可發(fā)現(xiàn)兩種方式編譯結(jié)果的不同,,如下圖: 用第二條命令生成的文檔被框架分成了三部分:包列表、類列表和類說明,。在包列表中選擇了某個(gè)包之后,,類列表中就會(huì)列出該包中的所有類;在類列表中選擇了某個(gè)類之后,,類說明部分就會(huì)顯示出該類的詳細(xì)文檔,。而用第一條命令生成的文檔只有兩部分,類列表和類說明,,沒有包列表,。這就是兩種方式生成文檔的最大區(qū)別了。 下面再來細(xì)說選項(xiàng),。 -public、-protected,、-package,、-private 四個(gè)選項(xiàng),,只需要任選其一即可。它們指定的顯示類成員的程度,。它們顯示的成員多少是一個(gè)包含的關(guān)系,,如下表:
-d 選項(xiàng)允許你定義輸出目錄。如果不用 -d 定義輸出目錄,,生成的文檔文件會(huì)放在當(dāng)前目錄下,。-d 選項(xiàng)的用法是 -d 目錄名 目錄名為必填項(xiàng),也就是說,,如果你使用了 -d 參數(shù),,就一定要為它指定一個(gè)目錄。這個(gè)目錄必須已經(jīng)存在了,,如果還不存在,,請(qǐng)?jiān)谶\(yùn)行 javadoc 之前創(chuàng)建該目錄。 -version 和 -author 用于控制生成文檔時(shí)是否生成 @version 和 @author 指定的內(nèi)容,。不加這兩個(gè)參數(shù)的情況下,,生成的文檔中不包含版本和作者信息。 -splitindex 選項(xiàng)將索引分為每個(gè)字母對(duì)應(yīng)一個(gè)文件,。默認(rèn)情況下,,索引文件只有一個(gè),且該文件中包含所有索引內(nèi)容,。當(dāng)然生成文檔內(nèi)容不多的時(shí)候,,這樣做非常合適,但是,,如果文檔內(nèi)容非常多的時(shí)候,,這個(gè)索引文件將包含非常多的內(nèi)容,顯得過于龐大,。使用 -splitindex 會(huì)把索引文件按各索引項(xiàng)的第一個(gè)字母進(jìn)行分類,,每個(gè)字母對(duì)應(yīng)一個(gè)文件。這樣,,就減輕了一個(gè)索引文件的負(fù)擔(dān),。 -windowtitle 選項(xiàng)為文檔指定一個(gè)標(biāo)題,該標(biāo)題會(huì)顯示在窗口的標(biāo)題欄上,。如果不指定該標(biāo)題,,而默認(rèn)的文檔標(biāo)題為“生成的文檔(無標(biāo)題)”。該選項(xiàng)的用法是: -windowtitle 標(biāo)題 標(biāo)題是一串沒有包含空格的文本,,因?yàn)榭崭穹怯糜诜指舾鲄?shù)的,,所以不能包含空格。同 -d 類似,,如果指定了 -windowtitle 選項(xiàng),,則必須指定標(biāo)題文本,。 到此為止,Java 文檔和 javadoc 就介紹完了,。javadoc 真的能讓我們?cè)?Java 注釋上做文章——生成開發(fā)文檔,。
|
|