注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败
当发现你的代码需要写注释的时候,一定要多思考一下,有没有办法通过代码表达,能不能把注释写的尽量的少
注释不一定解释的是正确的代码(程序员不能坚持维护注释)
1. 注释不能美化糟糕的代码
注释常见的动机:有糟糕的代码存在
带有少量注释的整洁而有表达力的代码,要比带有大量注释的零碎而复杂的代码好得多
2. 用代码来阐述
当代码本身不足以解释其行为时,而且代码又很少的时候,很多人都用注释来解释代码的实现
错误的写法
例如:
代码语言:java复制// Check to see if the employee is eligible for full benefits
// 检查员工是否有资格获得全额福利
if ((employee. flags & HOURLY_FLAG) && (employee.age > 65))
正确的写法
代码语言:java复制// 是否可获得全部利益
if(employee.isEligibleForFullBenefits())
3. 好的注释
不是说任何注释都不用添加,有些注释也是有利的
3.1 法律信息
有时,公司代码规范要求编写与法律有关的注释。例如,版权及著作权声明就是必须和
有理由在每个源文件开头注释处放置的内容。
这类注释不应是合同或法典。只要有可能,就指向一份标准许可或其他外部文档,而不要把所有条款放到注释中。
3.2 提供信息的注释(不建议用)
3.3 对意图的解释(不建议用)
3.4 阐释
有时,注释把某些晦涩难明的参数或返回值的意义翻译为某种可读形式,也会是有用的。通常,更好的方法是尽量让参数或返回值自身就足够清楚;但如果参数或返回值是某个标准库的一部分,或是你不能修改的代码,帮助阐释其含义的代码就会有用。
当然,这也会冒阐释性注释本身就不正确的风险。回头看看上例,你会发现想要确认注释的正确性有多难。这一方面说明了阐释有多必要,另外也说明了它有风险。所以,在写这类注释之前,考虑一下是否还有更好的办法,然后再加倍小心地确认注释正确性。
3.5 警示
类似这样的代码,可以适当添加注释
代码语言:java复制// 系统需要睡10s
thread.sleep(10)
3.6 TODO注释
当有未处理的事情的记得用TODO,但是记得一定要定时清理TODO注释
3.7 放大
3.8 公共API中的javadoc
4 坏注释
大多数注释都属于坏注释
4.1 喃喃自语
如果只是因为你觉得应该或者因为过程需要就添加注释,那就是无谓之举。如果你决定写注释,就要花必要的时间确保写出最好的注释。
例如,我在FitNesse中找到的这个例子,例中的注释大概确实有用。不过,作者太着急,或者没太花心思。他的喃喃自语变成了一个谜团。
看一个例子:
代码语言:java复制public void loadProperties(){
try{
String propertiesPath-propertiesLocation "/" PROPERTIES_FILE;
FileInputStream propertiesStrean=new FileInputStrean(propertiesPath);
loadedProperties.load(propertiesStream);
}catch(IOException e) {
// No properties files means all defaults are loaded 1
}
}
catch代码块中的注释是什么意思呢?显然对于作者有其意义,不过并没有好到足够的程度。很明显,如果出现IOException,就表示没有属性文件:在那种情况下,载入默认设置。但谁来装载默认设置呢?会在对loadProperties.load之前装载吗?抑或loadProperties.load捕获异常、装载默认设置、再向上传递异常?再或loadProperties.load在尝试载入文件前就装载所有默认设置?要么作者只是在安慰自己别在意catch代码块的留空?或者——这种可能最可怕一作者是想告诉自己,将来再回头写装载默认设置的代码?
4.2 多余的注释
读懂注释比读懂代码还要费时间,就属于多余的注释了
4.3 误导性注释
注释解释的代码并不是代码真正表达的含义
4.4 循轨式注释
所谓每个函数都要有Javadoc或每个变量都要有注释的规矩全然是愚蠢可笑的。这类注释徒然让代码变得散乱,满口胡言,令人迷惑不解。
4.5 日志式注释
每次修改,都把修改记录到注释中,日积月累,会变的冗长,代码变的凌乱
4.6 废话注释
代码已经表达清楚,还添加注释,属于废话注释
看一个例子
代码语言:java复制// The day of the month.
private int dayofMonth;
4.7 可怕的废话
Javadoc也可能是废话。下列Javadoc(来自某知名开源库)的目的是什么?答案:无。它们只是源自某种提供文档的不当愿望的废话注释。
代码语言:java复制/** The name.*/
private String name;
/**The version.*/
private String version;
/**The licenceName.*/
private String licenceName;
/** The version.*/
private String info;
4.8 能用函数或者变量时就别用注释
可以将代码抽取成函数,或者定义变量的代码,就不要用注释
例如:
错误的写法
代码语言:java复制// Check to see if the employee is eligible for full benefits
// 检查员工是否有资格获得全额福利
if ((employee. flags & HOURLY_FLAG) && (employee.age > 65))
正确的写法
代码语言:java复制// 是否可获得全部利益
if(employee.isEligibleForFullBenefits())
4.9 位置标记
不要乱用标记,只有在特别有价值的地方才可以使用
4.10 括号后面的注释
有时,程序员会在括号后面放置特殊的注释。尽管这对于含有深度嵌套结构的长函数可能有意义,但只会给我们更愿意编写的短小、封装的函数带来混乱。如果你发现自己想标记右括号,其实应该做的是缩短函数。
4.11 归属和署名
源代码控制系统非常善于记住是谁在何时添加了什么。没必要用那些小小的签名搞脏代码。你也许会认为,这种注释大概有助于他人了解应该和谁讨论这段代码。不过,事实却是注释在那儿放了一年又一年,越来越不准确,越来越和原作者没关系。
重申一下,源代码控制系统是这类信息最好的归属地。
4.12 注释掉的代码
千万不要把代码注释掉,如果没有作用了,记得及时删除
4.13 HTML注释
4.14 非本地信息
不要在本地注释的上下文环境中给出系统级的信息,例如项目的端口号
4.15 信息过多
别在注释中添加有趣的历史性话题或者无关的细节描述
4.16 不明显的联系
注释及其描述的代码之间的联系应该显而易见。如果你不嫌麻烦要写注释,至少让读者能看着注释和代码,并且理解注释所谈何物。
4.17 函数头
短函数不需要太多描述。为只做一件事的短函数选个好名字,通常要比写函数头注释要好。
4.18 非公共代码中的javadoc
虽然Javadoc对于公共API非常有用,但对于不打算作公共用途的代码就令人厌恶了。为系统中的类和函数生成Javadoc页并非总有用,而Javadoc注释额外的形式要求几乎等同于八股文章。