澳门新葡萄京官网首页Javadoc中的Tag说明

我非常确定,作为开发人员我们都喜爱技术文档。我们喜欢阅读文档、写文档,更不用说维护文档了,我简直爱死它了!

Tag的一些惯例

用过IDE或看过其他源码的小伙伴们应该都见过类似下面这样的注释

我也知道,每次你创建一个类或者一个方法,你都会想到要为此写文档。我也很确定你很享受于写文档,就像你喜欢偶尔美味的汉堡一样。但是有时候,只是有时候,你会想要松懈一下,也许这次就跳过文档部分。不幸的是,这种行为会很快地失控。

一些Tags的说明

  • @author:作者的姓名
  • @version:版本号
  • @param:对于参数的描述
  • @return:对于返回内容的描述
  • @exception (和@throws是同义词):异常类的名称和描述
  • @see:表示去查看参考资料
  • @since:表示这个变更或特性从什么时候或版本号等(由该标签中声明的内容决定)开始存在的
  • @serial:用于表示序列化的字段(include | exclude)
  • @deprecated:表示被弃用
  • @link:用法{@link package.class#member
    label
    }。插入一个带标签的链接,可以指向特定包、类或指定类的成员名称的文档。
  • @literal:用法{@literal
    text}。用来显示那些不用被HTML标记或嵌套javadoc标签解析的文本。
/** * 递归获取所有游戏分类 * @param int $id * @return array */

所以在这篇文章中,我想聊聊这个开发者的生活中关键但是通常被忽视并遗忘的部分。希望你会从此爱上文档,明白你的代码为什么能工作,能帮助你、你的团队和使用你的软件的数不尽的用户。

Tags的顺序

按照下面的顺序写tags:

  • @author (仅用于类和接口,必须的)
  • @version (仅用于类和接口,必须的)
  • @param (仅用于方法和构造函数)
  • @return (仅用于方法)
  • @exception (和@throws是同义词)
  • @see
  • @since
  • @serial (或者@serialField@serialData)
  • @deprecated

看得多了就大概知道了一些规律。为了使自己的代码更加规zhuang范bi,也开始有样学样地写着这些注释

为什么文档很重要

通常,开发者都不会忘记他们两个星期前写的代码。两个月以后甚至更长时间以后他们都会记得。即使我们保证我们从来不忘记我们写过的任何代码,写文档却有另一个理由并且更加重要。

对多个相同tags的排序

按照下面的惯例来使用多个相同tags。如果需要,可以用空白行(单*)来隔离这些包含多个相同tags的组。

  • 多个@author标签,应该按照发生时间顺序排列,最早的发在最上面。
  • 多个@param标签,应该按照参数的声明顺序排列。
  • 多个@throws标签(或@exception),应该按照异常名称的字母顺序排列。

其实这种注释格式是有自己的名字的,它就叫——

在写代码前理清思路

我会举一个自己的例子:我有一个开发SlideshowFX里一个全新特性的想法,这时我就想直接开始写代码并实现它。但我知道我不是做这项工程的唯一一个有激情的开发者。所以我的典型行为是这样的:

1. 写出以下类主体
public class BurgersManager {
}
2. 思考:“那么,我应该在BurgersManager类中有些CRUD操作”
3. 写下:
public…
4. 思考:“我应该返回什么值?目前来说void就可以”
5. public void addBurger(Burger burger) {
// TODO implement that later
}
public …
6. 思考:“我应该返回被吃掉的汉堡的实例吗?还是void就可以?就像第4步那样。。。”
7. public void eat(Burger burger, boolean fast) {
// TODO …
8. 告诉自己:“糟糕,咖啡时间了,我的咖啡呢。。。”
9. 搜索,喝咖啡,和同事交谈
10. 然后告诉自己:“回去工作吧,我刚才在做什么来着?”

我知道,你在这个例子中看到了自己,对吧?在创造性工作刚开始的时候,我们的思路有些混乱,所以当你直接开始写代码,那么代码也会很混乱。在写代码之前就考虑文档能够帮你理清思路并清除列出你要用代码实现的事。所以第一步应该是写出以下代码:

/**
* 此类通过提供CRUD操作来管理汉堡
* 采用单件模式。可以使用{<a href='http://www.jobbole.com/members/57845349'>@link</a> #getInstance()}来获得这个管理器的实例。
* 之后可以用以下方法来调用CRUD操作:
*/

{<a href='http://www.jobbole.com/members/57845349'>@link</a> #addBurger(Burger)} 用来增加汉堡,并受管理于
* 单件实例 ;
* @作者 Thierry Wasylczenko
* @版本 0.1
* <a href='http://www.jobbole.com/members/chchxinxinjun'>@since</a> BurgerQueen 1.0
*/
public class BurgersManager {

}

这就是一个简短的例子,这个例子能够:

  • 强迫你思考你创建的类的目的是什么
  • 帮你确定你的需要
  • 即使是在你休息之后也能帮你想起来你在做什么
  • 帮助你预估还有什么是需要做的

必须的Tags

按照惯例,每一个参数都应该有一个@param标签,即使描述很明显。每一个返回不是void的方法都应该有一个@return标签,即使这个标签和方法的描述内容重复。

PHPDOC

伙计,你是在团队中开发

你也许不是在单独工
作,你可能有尊敬的同事,你想和那些同事一起喝咖啡聊天。重点是,因为你喜欢他们,所以你想要帮助他们参与到你那令人兴奋的汉堡王的实现中去。为此,最好的做法就是确定他们在读你的代码时,有完美的文档参考。即使他们在你写代码之后的两个星期问你问题,你也能毫无犹豫地回答他们。

这就是另一个为什么文档很重要的理由:它能避免人们多次跑来问你你这复杂的算法是怎样运作的,或者为什么管理器中增加的汉堡没有同样被加到职工管理器的统计中去。在一个团队中,文档可以避免以下问题:

  • 在工作的时候被打断,之后难以返回继续工作;
  • 寻找可以回答问题的人,因为让其他成员知道了解自己是否能够回答问题;
  • 等待某个队员有时间回答他们的问题。
  • 所以写文档可以帮助团队提高生产力并专注于开发。
参考资料

How to Write Doc Comments for the Javadoc
Tool

PHPDoc 是一个 PHP 版的 Javadoc。它是一种注释 PHP
代码的正式标准。它支持通过类似 phpDocumentor 这样的外部文档生成器生成
API 文档,也可以帮助一些例如 Zend Studio, NetBeans, ActiveState Komodo
Edit and IDE 和 Aptana Studio 之类的 集成开发环境
理解变量类型和弱类型语言中的其他歧义并提供改进的代码完成,类型提示和除错功能。PHPDoc
可同时支持 面向对象 的和 面向过程的 代码。

让成功更进一步

这一点更加主观些。写Javadoc让我非常有成就感,因为当我再次使用我的API的时候,我写代码有文档参考,这帮我确保我没有忘记任何小细节。尽管我通常不会忘记,知道有文档在支撑我的记忆力也是件很棒的事。

看到IntelliJ
IDEA展示我的文档让我有“嘿,看,我就像是专业的,我做的东西太棒了,我甚至有文档噢”的感觉。在某些程度上的确是这样,不是吗?因为当你在使用一个
lib,其中的 log(String s, int i)
没有任何命名良好的参数描述,你一定像我一样在想“这个究竟是什么玩意儿?”。

不知道你怎样想的,我反正是觉得新的Javadoc设计特别赞。我认为让自己的文档整洁是非常棒的事。但是正如我说的,这只是我个人的感受。

以上摘自维基百科简单来说PHPDOC可以用来自动生成API文档。主流的IDE都会识别它,并在你coding中给予你相应的智能提示。使用PHPDOC有以下好处

写Javadoc的小技巧

在Javadoc中你有一下很好的标签可以使用:

  • @author
  • @version
  • @param
  • @return
  • @exception/@throws
  • @see
  • @since
  • @serial/@serialField/@serialData
  • @deprecated

但是这篇文章的目的并不是详细解释所有标签,而是作为文档作者和开发人员,我想分享我在写我的Javadoc时使用的技巧。

让你的代码更加规zhuang范bi,更易于理解

使用@link和@linkplain来指向某些代码

在我的Javadoc中,如果有依赖关系或者对文档有用,我会提及其它类和方法。为了使方法和类的浏览更简便,你可以使用@link。它是这样工作的:

  • {@link BurgersManager} 指向一个类
  • {@link BurgersManager burgers manager} 指向带有标签的类
  • {@link #eat(Burger, boolean)} 指向此类中的某个方法
  • {@link #eat(Burger, boolean) eat} 指向此类中带有标签的某个方法
  • {@link BurgersManagers#eat(Burger, boolean)} 指向其他类中的某个方法
  • {@link BurgersManagers#eat(Burger, boolean) burgers manager eat}
    指向其他带有标签的类的某个方法

@link 和 @linkplain 的区别是后者不会生成等宽字体的代码。

让你的IDE更懂你的代码,更加智能的提示和自动完成

使用@code来表明代码段

通常你会在Javadoc中发现一段代码,用来说明怎样使用方法和类,或者提供其它例子。为了正确显示代码,并防止一些像这样的标记被打断,你可以使用@code。

{<a href='http://www.jobbole.com/members/java12'>@code</a> 
List&lt;Burger&gt; burgers = new ArrayList&lt;&gt;();
  for(int index = 0; index &lt; 10; index++) {
    burgers.add(new Burger(“Burger #” + index)); 
  }
}

@code会为你生成标记。

如需API手册,可使用phpDocumentor来自动生成

使用@value来在文档中插入字段值

当你有一个常量,我可能想要它的值在文档中显示出来。有两个选择:

  • 自己插入这个值。但是如果这个值改变了,你必须更新你的文档,如果你绝对不会忘记这点,那你可以放心选择这个做法;
  • 使用@value来为你插入值,这样你就不用手动更新你的文档。

对我来说第二个选择是利用Javadoc工具的最佳方法,我会讨论这个方法。实际上,使用单一属性特别有用:

/**
* The default value for this field is {@value}.
* 这个域的默认值是{@value}.
*/
public static final String BURGER_SHOP_NAME = "Thierry's shop";

但你也可以指向其它常量,比如:

/**
* The default value for this field is {@value} when the value
* of {<a href='http://www.jobbole.com/members/57845349'>@link</a> #OWNER} is {@value #OWNER}.

* 这个域的默认值是{@value} 当
* {<a href='http://www.jobbole.com/members/57845349'>@link</a> #OWNER}的值为{@value #OWNER}.
*/
public static final String BURGER_SHOP_NAME = &quot;Thierry&#039;s shop&quot;;

/**
* The default owner of this awesome burger shop.

* 这家很棒的汉堡店的默认店主.
*/
public static final String OWNER = &quot; Thierry&quot;;

还等什么?快跟我一起来学习又好用又有逼格的phpDoc吧!

用@since来表明此特性的生效时间

通常,在你的代码中表明类或者方法何时开始生效非常有用。为此使用@since标签并在其后注明该特性执行的版本/年份:

/**
* This awesome class is for doing awesome things
* 这个棒呆了的类是用来做些棒呆了的事
* <a href='http://www.jobbole.com/members/chchxinxinjun'>@since</a> burger-core-0.1
* @version 0.2
*/
public class BurgersManager {

/**
* Allows to eat burgers
* 可以吃汉堡
* <a href='http://www.jobbole.com/members/chchxinxinjun'>@since</a> burger-core-0.2
*/
public void eat(Burger burger, boolean fast) {
// TODO
}
}

你可以看到,我把它用在了方法和类上,并且不止包含了版本号。事实上,现在我们的应用有很多不同的模块,这些模块可以有不同生命周期,即版本。说某个方法或者类从0.2版本开始生效并没有特别的意思。那么究竟是什么的0.2版本?这就是为什么我总是用一个相关的@since 来帮助我的同事第一眼就明白这些是什么时候开始生效的。

不止如此,这个标签的一个好处就是它可以帮你创建发布说明。等会儿,啥?不,并不是使用你最喜欢的IDE,比如IntelliJ
IDEA,然后查找包含“@since
burger-core-0.2″的文件。然后瞧,你可以找到自那个版本之后添加的所有方法和类。当然,这无法告诉你被更新的方法和类,而只会告诉你新添加的东西。但是你应该看到,这么简单的窍门多有用。

有关phpDoc的完整文档位于phpDocumentor官网。以下内容由我个人理解、提炼而来,而且我也还在学习中,如有失误还请各位多多指教

不要匿名,使用 @author

我非常讨厌的一件事:开发人员不承认自己的代码,并且不表明是他们为了一个糟糕的原因写了这糟糕的代码。如果你写了一段代码,要么承认它,要么去当经理。你可以用
@author
来表明你是这个类或者方法的作者。我认为把这标签既放在类上也放在方法上比较好,因为一个类的方法可能不是都是类的作者写的。

另一个好习惯就是,把一个方法或类的所有作者都加上。
试想一下,你和你的同事写了一个很棒的方法,而标签表明你是这个方法的唯一作者。有一天你去度假了,有人在读你的方法,但不是很明白并且想要一些细节。而是因为你被标为唯一的作者,他们不知道这个信息可以从和你一起写代码的同事那里很容易就获得。你知道我要说什么了,对吧?要记得给代码加@author来表
明作者。

@api

对非void方法要使用@return

我要说这一点对我来说非常有意义。有时候我看到类似以下例子中的代码就要跪了。

/** Get the address.
 * @return
 */
public String getAddress() { /* … */ }

为什么!?说真的,为什么你不填好@return?“因为只是一行而已,就是获得地址”。

不不不,请不要这样。如果你那样回答,是因为你的文档。怎么说呢,因为你的文档欠佳。是的,因为你可以很简单地写出一个更好的版本,而不是像以上你见到的糟糕的文档,
看:

/**
* Get the address of this burger shop. The address is of the following format:
* {<a href='http://www.jobbole.com/members/java12'>@code</a> address line 1
* address line 2
* zipcode city}
* @return the address of this burger shop or {<a href='http://www.jobbole.com/members/java12'>@code</a> null} if not filled.
*/

/**
*获取汉堡店的地址。地址格式:
* {<a href='http://www.jobbole.com/members/java12'>@code</a> 地址行1
* 地址行2
* 邮编 城市}
* @return 汉堡店的地址,如果没有填地址返回 {<a href='http://www.jobbole.com/members/java12'>@code</a> null}.
*/

好太多了,对吧?这样你的文档就有用了。我一直试着寻找给代码写文档的合适方法,因为有时候读者只读
@return 的内容,有时候也会读 @return
上面的内容,你添加一些说明就可以简单地避免疑惑。

表示这是一个提供给第三方使用的API接口

用@param说明参数的含义

有什么比看到方法使用一个像 i
这样的意义不明的参数而不加任何文档更加沮丧呢?有时候你可以通过方法的名字来猜到这个参数的目的,可是有时候就不行。所以在你的文档里,你应该使用@param来表明这个参数的含义,并说明可能的有效值。在我们的例子中,i可以是日志的级别:INFO,
DEBUG或者TRACE。这个标签另一个很有用的例子就是当这个值对应的是一个索引。有些情况下索引从0开始,有些情况下从1开始。@param就是用来描述这一区别的标签。

@author

生成文档

在代码中有文档是非常好的,但是现在你必须生成文档。所以你可以使用JDK提供的Java文档工具来生成它。

通过执行类似这样的命令:

javadoc {packages|source-files} [options]

你可以指定想要生成文档的包名或文件名,多个名字用空格分隔。

以下简要描述了一些jJavadoc工具能够接受的选项:

  • -author: 在生成的文档中生成@author用
  • -d: 要在当前目录之外生成文档的目录
  • -nodeprecated: 不为被标为@deprecated的代码生成文档
  • -protected: 包含protected和public类和类成员
  • -private: 包含private类和类成员
  • -public: 只包含public类和类成员

像IDE之类的工具也可以生成你的文档,但是如果它很好地格式化并且可以提供预览。

一些像Maven和Gradle这样的依赖管理工具也带有生成文档的阶段或任务。这很棒,因为你的文档可以一直紧随代码的发布来生成,这样它就一直是最新的。

作者格式@author [名称] []例如@author mokeyjay

总结

文档对于你的整个团队非常重要。它能帮你理清你在写什么代码,更重要的是,你为什么这样实现它。

希望这篇文章能让你想要写出更好的文档。如果是这样的话请告诉我你是否写了文档,你是怎样写的。

我的推特@twasyl,或者在下面留言都可以!

@copyright

版权声明。例如很多网站底部都有格式@copyright [描述]例如@copyright
1949-2016 China

@deprecated

不建议使用的、已过期的、将被删除的格式@deprecated []
[]例如@deprecated 1.0.0
新版本将不再包含此函数如果它是被其他方法所取代了,建议添加@see标记

@example

例子、示例、用例。也可表示方法返回值的例子格式@example [位置] [ []
] []例如@example demo.php 10 3 使用示例

@filesource

没看懂,如果你们看懂了请告诉我。传送门

@global

全局变量格式@global [类型][名称] @global
[类型][描述]我怀疑这里是源文档打错了,大概应该是格式@global
[类型][名称][描述]类型@global string name 用户名

@ignore

忽略格式@ignore
[]例如你在if和else的语句块中定义分别同一个变量但值不同时,可以通过此标记让phpDocumentor忽略其中一个,以免生成重复的文档。例如

if  { /** * This define will either be 'Unix' or 'Windows' */ define; } else { /** * @ignore */ define; }

@internal

仅限内部使用的格式@internal [描述]例如@internal 仅限内部测试使用

@license

协议,很常见的啦格式@license [] [名称]例如@license GPL

@link

链接,可用于辅助说明、引用文档等格式@link [url] []例如@link
不懂滚去问谷歌,别来烦我

@method

方法。这是用在类注释里的标记。特别适合一些动态加载的类,IDE无法自动提示出来,这时就可以通过写@method标记来告诉IDE我这类里有哪些方法格式@method
[返回值类型] [名称] []例如@method string google
向谷歌提问,返回答案内容

@package

包。但php没有包,所以就用来表示命名空间例如@package yiibasedb

@param

参数,用于函数和方法注释里的标记格式@param [Type] [name]
[]例如@param string title 文章标题

@property

类属性,与@method类似,可以告诉IDE我这类里有哪些属性格式@property
[Type] [name] []例如@property int id 用户id

@property-read

只读的属性。例如__get魔术方法能够取到的属性格式@property-read [Type]
[name] []例如@property-read int id 用户id

@property-write

只可写的属性。例如__set魔术方法能够设置的属性格式@property-write
[Type] [name] []例如@property-write string name 用户名

@return

返回值格式@return [类型] []]例如@return array 结果数组

@see

参考,类似@link,可与@deprecated联动格式@see [url或完整方法名]
[]例如@see yiibasedb::tableName()
旧方法table_name已弃用,请使用此方法替代

@since

从xx版本开始。例如从1.0之后添加了xx功能、删除了xx参数等格式@since
[1.0.0] []例如@since 1.0.2 添加了$b参数

@source

没看懂,如果你们看懂了请告诉我。传送门

@throws

可能会抛出的错误类型格式@throws [类型] []例如@throws LifeException
没钱了,好想死啊

@todo

待办。提示自己或他人还需要做些什么格式@todo [描述]例如@todo
这个类还没做异常处理

@uses

使用格式@uses [完整方法名] []例如@uses yiibasedb::$count
使用此属性计数

@var

变量格式@var [类型] [变量名] []例如@var int id 用户id

@version

版本号格式@version [] []例如@version 1.0.1
2016-07-03更新或者@version GIT:1f3197d01 来自GIT分支1f3197d01

发表评论

电子邮件地址不会被公开。 必填项已用*标注