Effective Java(3rd)-Item56 為所有公開的API元素編寫doc注釋

??如果API要可用顾翼,就必須對其進行文檔化投放。傳統(tǒng)上,API文檔是手工生成的适贸,保持與代碼的同步是一件苦差事灸芳。Java編程環(huán)境使用Javadoc實用程序簡化了這一任務。Javadoc使用特殊格式的文檔注釋(通常稱為doc注釋)從源代碼自動生成API文檔拜姿。
??雖然doc注釋約定不是正式語言的一部分烙样,但它們實際上構(gòu)成了每個Java程序員都應該知道的API。這些約定在如何編寫Doc注釋web頁面[Javadocguide]中進行了描述蕊肥。雖然自Java 4發(fā)布以來這個頁面沒有更新谒获,但它仍然是一個非常寶貴的資源。在Java 9中添加了一個重要的doc標簽壁却,{@index};Java 8中的一個究反,{@implSpec};Java 5中有兩個,{@literal}和{@code}儒洛。上述web頁面中缺少這些標記精耐,但將在本項目中討論。
??要正確地記錄API琅锻,必須在每個導出的類卦停、接口、構(gòu)造函數(shù)恼蓬、方法和字段聲明之前加上doc注釋惊完。如果一個類是可序列化的,還應該記錄它的序列化形式(item87 )处硬。在缺少doc注釋的情況下小槐,Javadoc所能做的最好的事情就是將聲明復制為受影響API元素的唯一文檔。使用缺少文檔注釋的API是令人沮喪和容易出錯的荷辕。公共類不應該使用默認構(gòu)造函數(shù)凿跳,因為無法為它們提供doc注釋。要編寫可維護的代碼疮方,還應該為大多數(shù)未導出的類控嗜、接口、構(gòu)造函數(shù)骡显、方法和字段編寫doc注釋疆栏,盡管這些注釋不需要像導出API元素那樣完整曾掂。

??方法的doc注釋應該簡潔地描述方法與其客戶機之間的契約。除為繼承而設計的類中的方法(item19 )外壁顶,契約應該說明方法做了什么珠洗,而不是它如何做它的工作。doc注釋應該枚舉方法的所有前置條件(這些條件必須為真若专,以便客戶機調(diào)用它們)和后置條件(這些條件是在調(diào)用成功完成后才為真)险污。通常,先決條件是通過@throw標簽的未檢查異常隱式描述的富岳;每個未檢查異常對應于一個先決條件違反蛔糯。此外,可以在前置條件及其@param標記中指定受影響的參數(shù)窖式。

??除了前置條件和后置條件外蚁飒,方法還應該記錄任何副作用。副作用是系統(tǒng)狀態(tài)的一個可觀察到的變化萝喘,它不是實現(xiàn)后置條件所明顯需要的淮逻。例如,如果一個方法啟動了一個后臺線程阁簸,文檔應該注意它爬早。
??要完整地描述方法的契約,doc注釋應該為每個參數(shù)都有一個@param標記启妹,一個@return標記(除非方法有一個void返回類型)筛严,以及一個@throw標記(對于方法拋出的每個異常,無論是否是可檢查的)( item74 )饶米。如果@return標記中的文本與方法的描述相同桨啃,則可以忽略它,這取決于您所遵循的編碼標準檬输。

??按照慣例照瘾,@param標記或@return標記后面的文本應該是一個名詞短語,描述參數(shù)或返回值所表示的值丧慈。算術(shù)表達式很少用來代替名詞短語;有關(guān)示例析命,請參見BigInteger。@throw標記后面的文本應該包含單詞“if”逃默,后跟描述引發(fā)異常的條件的子句鹃愤。按照慣例,@param笑旺、@return或@throw標記后面的短語或子句不以句號結(jié)束昼浦。以下的doc注釋說明了所有這些約定:

image.png

??請注意在這個doc注釋中使用HTML標記(<p> 和<i>). 。Javadoc實用程序?qū)oc注釋轉(zhuǎn)換為HTML, doc注釋中的任意HTML元素最終會出現(xiàn)在生成的HTML文檔中筒主。有時候关噪,程序員甚至會在他們的doc注釋中嵌入HTML表,盡管這種情況很少見乌妙。
??還要注意在@throw子句中的代碼片段周圍使用Javadoc {@code}標記使兔。這個標記有兩個目的:它使代碼片段以代碼字體呈現(xiàn),并且它抑制了代碼片段中HTML標記和嵌套Javadoc標記的處理藤韵。后一個屬性允許我們在代碼片段中使用小于號(<)虐沥,即使它是一個HTML元字符。要在doc注釋中包含多行代碼示例泽艘,使用Javadoc {@code}標記封裝在HTML<pre>標記中欲险。換句話說,在代碼示例之前加上字符<pre>{@code and follow it with }</pre>.這保護線在代碼中中斷匹涮,并消除了轉(zhuǎn)義HTML元字符的需要天试,但不需要轉(zhuǎn)義at符號(@),如果代碼示例使用注釋然低,則必須轉(zhuǎn)義@喜每。
??最后,請注意doc注釋中使用的單詞“this list”雳攘。按照慣例带兜,“this”指的是在doc注釋中為實例方法使用方法時調(diào)用方法的對象。
??正如第15項中提到的吨灭,當您為繼承設計一個類時刚照,您必須記錄它的自用模式,以便程序員知道覆蓋它的方法的語義喧兄。這些自用模式應該使用在Java 8中添加的@implSpec標記來記錄涩咖。回想一下繁莹,普通的doc注釋描述了方法與其客戶機之間的契約;相反檩互,@implSpec注釋描述了方法與其子類之間的契約,允許子類依賴于實現(xiàn)行為(如果它們繼承了方法或通過super調(diào)用方法)咨演。下面是它在實踐中的樣子:


image.png

??Java 9開始闸昨,Javadoc實用程序仍然忽略@implSpec標記,除非您通過命令行開關(guān)-標記“implSpec:a:Implementation Requirements:”薄风。希望在后續(xù)的版本中可以糾正這個錯誤饵较。
??不要忘記,您必須采取特殊的操作來生成包含HTML元字符的文檔遭赂,比如小于號(<)循诉、大于號(>)和與號(&)。將這些字符放到文檔中最好的方法是用{@literal}標記包圍它們撇他,這將抑制HTML標記和嵌套Javadoc標記的處理茄猫。它類似于{@code}標記狈蚤,只是它不以代碼字體呈現(xiàn)文本。例如划纽,這個Javadoc片段:


image.png

??生成文檔:“如果|r| < 1脆侮,則幾何級數(shù)收斂∮铝樱”使用相同的結(jié)果文檔靖避,{@literal}標記可以放在小于號周圍,而不是整個不等式周圍比默,但是doc注釋在源代碼中可讀性較差幻捏。這說明了doc注釋在源代碼和生成的文檔中都應該是可讀的。如果不能同時實現(xiàn)這兩個目標命咐,生成的文檔的可讀性將超過源代碼的可讀性篡九。
??每個doc注釋的第一個“句子”(定義如下)成為注釋所屬元素的摘要描述。例如侈百,255頁doc注釋中的摘要描述是“返回列表中指定位置的元素”瓮下。摘要描述必須獨立地描述它總結(jié)的元素的功能。為了避免混淆,類或接口中的任何兩個成員或構(gòu)造函數(shù)都不應具有相同的摘要描述钝域。特別注意重載讽坏,對于重載,通常使用相同的第一句話是很自然的(但在doc注釋中是不可接受的)例证。
??如果預期的摘要描述包含句點路呜,請小心,因為句點可能會提前終止描述织咧。例如胀葱,以短語開頭的doc注釋"“A college degree, such as B.S., M.S. or Ph.D.”將在總結(jié)描述的結(jié)果““A college degree, such as B.S., M.S.” ”問題是摘要描述在第一個句點結(jié)束,然后是空格笙蒙、制表符或行結(jié)束符(或第一個塊標記)[Javadoc-ref]抵屿。這里是縮寫“M.S.”中的第二個句號后面跟著一個空格。最好的解決方案是用{@literal}標記來包圍違規(guī)的句點和任何相關(guān)的文本捅位,這樣源代碼中的句點后面就不會有空格了:

image.png

??說摘要描述是doc注釋中的第一句話有點誤導人轧葛。按照慣例,它很少應該是一個完整的句子艇搀。對于方法和構(gòu)造函數(shù)尿扯,摘要描述應該是一個動詞短語(包括任何對象),描述方法執(zhí)行的操作焰雕。例如:


image.png

??如這些例子所示衷笋,使用第三人稱陳述句時態(tài)(“return the number”)而不是第二人稱祈使句(“return the number”)。
??對于類矩屁、接口和字段辟宗,摘要描述應該是一個名詞短語爵赵,描述由類或接口的實例或字段本身表示的事物。例如:


image.png

??在Java 9中慢蜓,客戶端索引被添加到Javadoc生成的HTML中亚再。這個索引以頁面右上角的搜索框的形式出現(xiàn)郭膛,它簡化了導航大型API文檔集的任務晨抡。當您在框中鍵入時,您將得到一個匹配頁面的下拉菜單则剃。API元素(如類耘柱、方法和字段)是自動索引的。有時棍现,您可能希望索引對您的API很重要的其他術(shù)語调煎。為此添加了{@index}標記。對doc注釋中出現(xiàn)的術(shù)語進行索引己肮,就像將其包裝在這個標簽中一樣簡單士袄,如下面的片段所示:

  • This method complies with the {@index IEEE 754} standard.

??泛型、枚舉和注釋在doc注釋中需要特別注意谎僻。當記錄泛型類型或方法時娄柳,請確保記錄所有類型參數(shù):

image.png

??在記錄枚舉類型時,一定要記錄常量艘绍、類型和任何公共方法赤拒。注意,如果文檔很短诱鞠,你可以把整個文檔注釋放在一行:

image.png

??在記錄注釋類型時挎挖,一定要記錄任何成員和類型本身。用名詞短語記錄成員航夺,就好像它們是字段一樣蕉朵。對于類型的摘要描述,請使用動詞短語阳掐,它表示當程序元素具有此類注釋時的含義:

image.png

??包級別的doc注釋應該放在名為packageinfo.java的文件中始衅。除了這些注釋之外,package-info.java必須包含一個包聲明锚烦,并且可能包含關(guān)于這個聲明的注釋觅闽。類似地,如果您選擇使用模塊系統(tǒng)( item15)涮俄,模塊級別的注釋應該放在模塊-info.java文件中蛉拙。

??在文檔中經(jīng)常忽略的api的兩個方面是線程安全性和可序列化性。無論類或靜態(tài)方法是否線程安全彻亲,都應該記錄它的線程安全級別孕锄,如項目82所述吮廉。如果一個類是可序列化的,您應該記錄它的序列化形式畸肆,如第87項中所述宦芦。
??Javadoc具有“繼承”方法注釋的能力。如果API元素沒有doc注釋轴脐,Javadoc將搜索最特定的適用doc注釋调卑,優(yōu)先選擇接口而不是超類。搜索算法的詳細信息可以在Javadoc參考指南[Javadoc-ref]中找到大咱。您還可以使用{@inheritDoc}標記從超類型繼承部分doc注釋恬涧。這意味著類可以重用它們實現(xiàn)的接口中的doc注釋,而不是復制這些注釋碴巾。這個工具有潛力減少維護多個幾乎相同的doc注釋集的負擔溯捆,但是它使用起來很棘手,并且有一些限制厦瓢。這些細節(jié)超出了這本書的范圍提揍。
??關(guān)于文檔注釋,應該添加一個警告煮仇。雖然有必要為所有導出的API元素提供文檔注釋劳跃,但這并不總是足夠的。對于由多個相互關(guān)聯(lián)的類組成的復雜api欺抗,通常需要用描述API總體架構(gòu)的外部文檔來補充文檔注釋售碳。如果存在這樣的文檔,相關(guān)的類或包文檔注釋應該包含到它的鏈接绞呈。
??Javadoc會自動檢查是否符合本項目中的許多建議贸人。在Java 7中,需要命令行開關(guān)-Xdoclint來獲得這種行為佃声。在Java 8和Java 9中艺智,默認情況下啟用了check。諸如checkstyle之類的IDE插件在檢查是否符合這些建議方面走得更遠[Burn01]圾亏。還可以通過HTML有效性檢查器運行Javadoc生成的HTML文件來降低doc注釋中出現(xiàn)錯誤的可能性十拣。這將檢測HTML標記的許多不正確用法。有幾個這樣的檢查器可供下載志鹃,您可以使用W3C標記驗證服務[W3C-validator]在web上驗證HTML夭问。在驗證生成的HTML時,請記住曹铃,從Java 9開始缰趋,Javadoc就能夠生成HTML5和HTML 4.01,盡管默認情況下它仍然生成HTML 4.01。如果希望Javadoc生成HTML5秘血,請使用-html5命令行開關(guān)味抖。
??本項目中描述的約定涵蓋了基本內(nèi)容。盡管撰寫本文時已經(jīng)有15年的歷史灰粮,但編寫doc注釋的最終指南仍然是如何編寫doc注釋[Javadoc-guide]仔涩。
??如果您遵循本項目中的指導原則,生成的文檔應該提供對API的清晰描述粘舟。然而熔脂,唯一確定的方法是閱讀Javadoc實用程序生成的web頁面。對于其他人將使用的每個API蓖乘,都值得這樣做锤悄。正如測試程序幾乎不可避免地會導致對代碼的一些更改一樣韧骗,閱讀文檔通常也會導致對doc注釋的一些較小更改嘉抒。
??總之,文檔注釋是記錄API的最佳袍暴、最有效的方法些侍。應該認為所有導出的API元素都必須使用它們。采用符合標準約定的一致樣式政模。請記住岗宣,在文檔注釋中允許任意HTML,并且必須轉(zhuǎn)義HTML元字符淋样。
本文寫于2019.7.18耗式,歷時1天

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市趁猴,隨后出現(xiàn)的幾起案子刊咳,更是在濱河造成了極大的恐慌,老刑警劉巖儡司,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娱挨,死亡現(xiàn)場離奇詭異,居然都是意外死亡捕犬,警方通過查閱死者的電腦和手機跷坝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碉碉,“玉大人柴钻,你說我怎么就攤上這事」噶福” “怎么了贴届?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我粱腻,道長庇配,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任绍些,我火速辦了婚禮捞慌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘柬批。我一直安慰自己啸澡,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布氮帐。 她就那樣靜靜地躺著嗅虏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪上沐。 梳的紋絲不亂的頭發(fā)上皮服,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音参咙,去河邊找鬼龄广。 笑死,一個胖子當著我的面吹牛蕴侧,可吹牛的內(nèi)容都是我干的择同。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼净宵,長吁一口氣:“原來是場噩夢啊……” “哼敲才!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起择葡,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤紧武,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后刁岸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脏里,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年虹曙,在試婚紗的時候發(fā)現(xiàn)自己被綠了迫横。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡酝碳,死狀恐怖矾踱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疏哗,我是刑警寧澤呛讲,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響贝搁,放射性物質(zhì)發(fā)生泄漏吗氏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一雷逆、第九天 我趴在偏房一處隱蔽的房頂上張望弦讽。 院中可真熱鬧,春花似錦膀哲、人聲如沸往产。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仿村。三九已至,卻和暖如春兴喂,著一層夾襖步出監(jiān)牢的瞬間蔼囊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工瞻想, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留压真,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓蘑险,卻偏偏與公主長得像,于是被迫代替她去往敵國和親岳悟。 傳聞我的和親對象是個殘疾皇子佃迄,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • [{"reportDate": "2018-01-23 23:28:49","fluctuateCause": n...
    加勒比海帶_4bbc閱讀 765評論 1 2
  • 目錄: Android:Android 0.*Android 1.*Android 2.*Android 3.*A...
    敲代碼的令狐蔥閱讀 3,778評論 0 2
  • 生活娶耍,很多人不滿于生活的現(xiàn)狀 其實當下的生活方式都是以往自己選擇的 有些人目標很明確断序,要掙很多很多的錢 但當時沒有...
    Mary妹善閱讀 215評論 0 0
  • 問題——行動——轉(zhuǎn)折 有一個自稱張方林的山西太原經(jīng)偵上網(wǎng)逃犯,打我支隊值班室電話稱要投案自首并留下聯(lián)系電話范嘱,經(jīng)核...
    Alice小香閱讀 586評論 0 0
  • 小燕和她的男人離婚了滔灶,離婚的原因只有一句話:我已經(jīng)完全死于他普碎。 女人實際上非常重視感情。如果他們沒有受到男人的傷害...
    少女心兩三事閱讀 226評論 0 0