【Java】浅谈JavaDoc文档注释
JavaDoc文檔注釋
- 文檔注釋
- JavaDoc標記
- 文檔注釋示例
- 基于Eclipse IDE的JavaDoc實戰
- 后記
文檔注釋
我們知道,Java有三種注釋:
- 單行注釋://
- 多行注釋:/* */
- 文檔注釋:/** */
這里,文檔注釋是我們探討的主角。
文檔注釋可以在程序中嵌入關于程序的信息。我們可以利用JDK提供的javadoc實用程序提取這些信息,并放到HTML文件中。
文檔注釋使得程序的文檔化變得簡單,是Java的重要內容。
感興趣的看一下Java11的API文檔吧。
比如java.util.Scanner的網頁版官檔內容如下:
而我們借助Eclipse IDE查看一下JDK源碼:
上面的兩個圖是Scanner類的部分文檔注釋截圖,可見文檔注釋里不僅僅有大量的英文注釋用于解釋,更是有許多@(javadoc標記),還有<></>(HTML文檔),內容十分豐富。
當然,其他類也是類似的,因為整個Java API庫就是通過這種方式文檔化的。
另說:JDK9+開始JavaDoc開始支持模塊(Java模塊的概念從JDK9正式引入Java體系)
JavaDoc標記
| @author | 標識作者 |
| {@code} | 以代碼字體原樣顯示信息,但不轉換成HTML樣式 |
| @deprecated | 指定程序元素已經過時 |
| {@docRoot} | 指定當前文檔的根目錄路徑 |
| @exception | 標識某個方法或者構造函數拋出的異常 |
| @hidden | 禁止某元素顯示在文檔中 |
| {@index} | 給索引指定術語 |
| {@inheritDoc} | 直接從父類中繼承文檔注釋 |
| {@link} | 插入指向另一個主題的內部鏈接 |
| {@linkplain} | 插入指向另一個主題的內部鏈接,但以純文本字體顯示鏈接 |
| {@literal} | 原樣式顯示信息,但不轉換成HTML樣式 |
| @param | 文檔化形參 |
| @provides | 文檔化模塊提供的服務 |
| @return | 文檔化方法的返回值 |
| @see | 指定對另一個主題的鏈接 |
| @serial | 文檔化默認的可序列化域 |
| @serialData | 文檔化writeObject()或writeExternal()方法寫入的數據 |
| @serialField | 文檔化ObjectStreamField組件 |
| @since | 聲明引入特定更改的版本號 |
| {@summary} | 文檔化某項的摘要(JDK10+) |
| @throws | 相當于@exception |
| @uses | 文檔化模塊所需要的服務(JDK9+) |
| {@value} | 顯示一個常量的值,該常量必須是靜態域 |
| @version | 指定程序元素的版本 |
文檔注釋示例
/*** This class test class Demo* @author BlankSpace* @version 4.1*/ public class Test {//balabala }然后,看一下Scanner類類名上面的完整文檔注釋(Java每個類都是一大坨這個)
/*** A simple text scanner which can parse primitive types and strings using* regular expressions.** <p>A {@code Scanner} breaks its input into tokens using a* delimiter pattern, which by default matches whitespace. The resulting* tokens may then be converted into values of different types using the* various {@code next} methods.** <p>For example, this code allows a user to read a number from* {@code System.in}:* <blockquote><pre>{@code* Scanner sc = new Scanner(System.in);* int i = sc.nextInt();* }</pre></blockquote>** <p>As another example, this code allows {@code long} types to be* assigned from entries in a file {@code myNumbers}:* <blockquote><pre>{@code* Scanner sc = new Scanner(new File("myNumbers"));* while (sc.hasNextLong()) {* long aLong = sc.nextLong();* }* }</pre></blockquote>** <p>The scanner can also use delimiters other than whitespace. This* example reads several items in from a string:* <blockquote><pre>{@code* String input = "1 fish 2 fish red fish blue fish";* Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");* System.out.println(s.nextInt());* System.out.println(s.nextInt());* System.out.println(s.next());* System.out.println(s.next());* s.close();* }</pre></blockquote>* <p>* prints the following output:* <blockquote><pre>{@code* 1* 2* red* blue* }</pre></blockquote>** <p>The same output can be generated with this code, which uses a regular* expression to parse all four tokens at once:* <blockquote><pre>{@code* String input = "1 fish 2 fish red fish blue fish";* Scanner s = new Scanner(input);* s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");* MatchResult result = s.match();* for (int i=1; i<=result.groupCount(); i++)* System.out.println(result.group(i));* s.close();* }</pre></blockquote>** <p>The <a id="default-delimiter">default whitespace delimiter</a> used* by a scanner is as recognized by {@link Character#isWhitespace(char)* Character.isWhitespace()}. The {@link #reset reset()}* method will reset the value of the scanner's delimiter to the default* whitespace delimiter regardless of whether it was previously changed.** <p>A scanning operation may block waiting for input.** <p>The {@link #next} and {@link #hasNext} methods and their* companion methods (such as {@link #nextInt} and* {@link #hasNextInt}) first skip any input that matches the delimiter* pattern, and then attempt to return the next token. Both {@code hasNext()}* and {@code next()} methods may block waiting for further input. Whether a* {@code hasNext()} method blocks has no connection to whether or not its* associated {@code next()} method will block. The {@link #tokens} method* may also block waiting for input.** <p>The {@link #findInLine findInLine()},* {@link #findWithinHorizon findWithinHorizon()},* {@link #skip skip()}, and {@link #findAll findAll()}* methods operate independently of the delimiter pattern. These methods will* attempt to match the specified pattern with no regard to delimiters in the* input and thus can be used in special circumstances where delimiters are* not relevant. These methods may block waiting for more input.** <p>When a scanner throws an {@link InputMismatchException}, the scanner* will not pass the token that caused the exception, so that it may be* retrieved or skipped via some other method.** <p>Depending upon the type of delimiting pattern, empty tokens may be* returned. For example, the pattern {@code "\\s+"} will return no empty* tokens since it matches multiple instances of the delimiter. The delimiting* pattern {@code "\\s"} could return empty tokens since it only passes one* space at a time.** <p> A scanner can read text from any object which implements the {@link* java.lang.Readable} interface. If an invocation of the underlying* readable's {@link java.lang.Readable#read read()} method throws an {@link* java.io.IOException} then the scanner assumes that the end of the input* has been reached. The most recent {@code IOException} thrown by the* underlying readable can be retrieved via the {@link #ioException} method.** <p>When a {@code Scanner} is closed, it will close its input source* if the source implements the {@link java.io.Closeable} interface.** <p>A {@code Scanner} is not safe for multithreaded use without* external synchronization.** <p>Unless otherwise mentioned, passing a {@code null} parameter into* any method of a {@code Scanner} will cause a* {@code NullPointerException} to be thrown.** <p>A scanner will default to interpreting numbers as decimal unless a* different radix has been set by using the {@link #useRadix} method. The* {@link #reset} method will reset the value of the scanner's radix to* {@code 10} regardless of whether it was previously changed.** <h3> <a id="localized-numbers">Localized numbers</a> </h3>** <p> An instance of this class is capable of scanning numbers in the standard* formats as well as in the formats of the scanner's locale. A scanner's* <a id="initial-locale">initial locale </a>is the value returned by the {@link* java.util.Locale#getDefault(Locale.Category)* Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link* #useLocale useLocale()} method. The {@link #reset} method will reset the value of the* scanner's locale to the initial locale regardless of whether it was* previously changed.** <p>The localized formats are defined in terms of the following parameters,* which for a particular locale are taken from that locale's {@link* java.text.DecimalFormat DecimalFormat} object, {@code df}, and its and* {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,* {@code dfs}.** <blockquote><dl>* <dt><i>LocalGroupSeparator </i>* <dd>The character used to separate thousands groups,* <i>i.e.,</i> {@code dfs.}{@link* java.text.DecimalFormatSymbols#getGroupingSeparator* getGroupingSeparator()}* <dt><i>LocalDecimalSeparator </i>* <dd>The character used for the decimal point,* <i>i.e.,</i> {@code dfs.}{@link* java.text.DecimalFormatSymbols#getDecimalSeparator* getDecimalSeparator()}* <dt><i>LocalPositivePrefix </i>* <dd>The string that appears before a positive number (may* be empty), <i>i.e.,</i> {@code df.}{@link* java.text.DecimalFormat#getPositivePrefix* getPositivePrefix()}* <dt><i>LocalPositiveSuffix </i>* <dd>The string that appears after a positive number (may be* empty), <i>i.e.,</i> {@code df.}{@link* java.text.DecimalFormat#getPositiveSuffix* getPositiveSuffix()}* <dt><i>LocalNegativePrefix </i>* <dd>The string that appears before a negative number (may* be empty), <i>i.e.,</i> {@code df.}{@link* java.text.DecimalFormat#getNegativePrefix* getNegativePrefix()}* <dt><i>LocalNegativeSuffix </i>* <dd>The string that appears after a negative number (may be* empty), <i>i.e.,</i> {@code df.}{@link* java.text.DecimalFormat#getNegativeSuffix* getNegativeSuffix()}* <dt><i>LocalNaN </i>* <dd>The string that represents not-a-number for* floating-point values,* <i>i.e.,</i> {@code dfs.}{@link* java.text.DecimalFormatSymbols#getNaN* getNaN()}* <dt><i>LocalInfinity </i>* <dd>The string that represents infinity for floating-point* values, <i>i.e.,</i> {@code dfs.}{@link* java.text.DecimalFormatSymbols#getInfinity* getInfinity()}* </dl></blockquote>** <h4> <a id="number-syntax">Number syntax</a> </h4>** <p> The strings that can be parsed as numbers by an instance of this class* are specified in terms of the following regular-expression grammar, where* Rmax is the highest digit in the radix being used (for example, Rmax is 9 in base 10).** <dl>* <dt><i>NonAsciiDigit</i>:* <dd>A non-ASCII character c for which* {@link java.lang.Character#isDigit Character.isDigit}{@code (c)}* returns true** <dt><i>Non0Digit</i>:* <dd>{@code [1-}<i>Rmax</i>{@code ] | }<i>NonASCIIDigit</i>** <dt><i>Digit</i>:* <dd>{@code [0-}<i>Rmax</i>{@code ] | }<i>NonASCIIDigit</i>** <dt><i>GroupedNumeral</i>:* <dd><code>( </code><i>Non0Digit</i>* <i>Digit</i>{@code ?* }<i>Digit</i>{@code ?}* <dd> <code>( </code><i>LocalGroupSeparator</i>* <i>Digit</i>* <i>Digit</i>* <i>Digit</i>{@code )+ )}** <dt><i>Numeral</i>:* <dd>{@code ( ( }<i>Digit</i>{@code + )* | }<i>GroupedNumeral</i>{@code )}** <dt><a id="Integer-regex"><i>Integer</i>:</a>* <dd>{@code ( [-+]? ( }<i>Numeral</i>{@code* ) )}* <dd>{@code | }<i>LocalPositivePrefix</i> <i>Numeral</i>* <i>LocalPositiveSuffix</i>* <dd>{@code | }<i>LocalNegativePrefix</i> <i>Numeral</i>* <i>LocalNegativeSuffix</i>** <dt><i>DecimalNumeral</i>:* <dd><i>Numeral</i>* <dd>{@code | }<i>Numeral</i>* <i>LocalDecimalSeparator</i>* <i>Digit</i>{@code *}* <dd>{@code | }<i>LocalDecimalSeparator</i>* <i>Digit</i>{@code +}** <dt><i>Exponent</i>:* <dd>{@code ( [eE] [+-]? }<i>Digit</i>{@code + )}** <dt><a id="Decimal-regex"><i>Decimal</i>:</a>* <dd>{@code ( [-+]? }<i>DecimalNumeral</i>* <i>Exponent</i>{@code ? )}* <dd>{@code | }<i>LocalPositivePrefix</i>* <i>DecimalNumeral</i>* <i>LocalPositiveSuffix</i>* <i>Exponent</i>{@code ?}* <dd>{@code | }<i>LocalNegativePrefix</i>* <i>DecimalNumeral</i>* <i>LocalNegativeSuffix</i>* <i>Exponent</i>{@code ?}** <dt><i>HexFloat</i>:* <dd>{@code [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+* ([pP][-+]?[0-9]+)?}** <dt><i>NonNumber</i>:* <dd>{@code NaN* | }<i>LocalNan</i>{@code* | Infinity* | }<i>LocalInfinity</i>** <dt><i>SignedNonNumber</i>:* <dd>{@code ( [-+]? }<i>NonNumber</i>{@code )}* <dd>{@code | }<i>LocalPositivePrefix</i>* <i>NonNumber</i>* <i>LocalPositiveSuffix</i>* <dd>{@code | }<i>LocalNegativePrefix</i>* <i>NonNumber</i>* <i>LocalNegativeSuffix</i>** <dt><a id="Float-regex"><i>Float</i></a>:* <dd><i>Decimal</i>* {@code | }<i>HexFloat</i>* {@code | }<i>SignedNonNumber</i>** </dl>* <p>Whitespace is not significant in the above regular expressions.** @since 1.5*/基于Eclipse IDE的JavaDoc實戰
我們用自己寫的順序表的Project生成JavaDoc。
右鍵工程,點擊Export:
選Javadoc:
我們目前只需要public的,畢竟這是API文檔,一直點擊next或者finish:
最后一個next有一個JRE的問題,自己處理一下就行,一般不用動。然后點擊Yes To All:
瞬間傻掉……這是啥?
我們看一下,GBK編碼?哦,想到我用的是UTF-8編碼。那就拷過去,換個work-space唄,我還有一個gbk的work-space,再生成:
原來……直接就亂碼了,那就文本復制,最簡單了!
我再來:
咋還Warning?
原來是我有的@param、@return沒有進行說明,以后注意。不過這次就算了,先看看結果:
下面是SequentialList類的JavaDoc文檔的一部分:
簡單的完成了任務!BINGO!
后記
Java文檔注釋非常方便,也很好用,建議編程人員養成良好的編程習慣,認真寫注釋。
另外,現在的IDE非常便捷,能夠在你輸入/**和回車的時候直接生成文檔注釋結構。比如在寫完一個方法以后,這么做IDE會直接生成包含@param、@return、@throws等在內的基本文檔注釋,把變量名等直接給出了,很是方便。
而且IDE里如果有良好的文檔注釋,鼠標放在類名等上時,IDE會給出基本解釋(Eclipse)。
Eclipse的@param在生成以后就那個樣子了,除非重新生成,否則即使改變變量名也不會引起警告或者錯誤(生成文檔時除外),而IDEA則會給不匹配的文檔注釋警告報錯(紅字提示),很人性化。
Eclipse里的文檔注釋是白色的,挺丑;IDEA里是綠色、斜體,蠻好看的。
總結
以上是生活随笔為你收集整理的【Java】浅谈JavaDoc文档注释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【VB.NET】VB.NET数据库技术问
- 下一篇: 【面向对象】面向对象程序设计测试题8-对