第4章 注释

目录

4.0 前言

4.1 注释不能美化糟糕的代码

4.2 用代码来阐述

4.3 好注释

4.3.1 法律信息

4.3.2 提供信息的注释

4.3.3 对意图的解释

4.3.4 阐释

4.3.5 警示

4.3.6 TODO注释

4.3.7 放大

4.3.8 公共API中的Javadoc

4.4 坏注释

4.4.1 喃喃自语

4.4.2 多余的注释

4.4.3 误导性注释

4.4.4 循规式注释

4.4.5 日志式注释

4.4.6 废话注释

4.4.7 可怕的废话

4.4.8 能用函数或变量时就别用注释

4.4.9 位置标记

4.4.10 括号后面的注释

4.4.11 归属与署名

4.4.12 注释掉的代码

4.4.13 HTML注释

4.4.14 非本地信息

4.4.15 信息过多

4.4.16 不明显的联系

4.4.17 函数头

4.4.18 非公共代码中的Javadoc


4.0 前言

  • 什么也比不上放置良好的注释来得有用。什么也不会比乱七八糟的注释更有本事搞乱一个模块。什么也不会比陈旧、提供错误信息的注释更有破坏性。

  • 注释会撒谎。也不是说总是如此或有意如此,但出现得实在太频繁。注释存在的时间越久,就离其所描述的代码越远,越来越变得全然错误。原因很简单。程序员不能坚持维护注释。

  • 真实只在一处地方有:代码。只有代码能忠实地告诉我们它做的事情。那是唯一真正准确的信息来源。所以,尽管有时也需要注释,我们也该多花心思尽量减少注释量。

4.1 注释不能美化糟糕的代码

带有少量注释的整洁而有表达力的代码,要比带有大量注释的零碎而复杂的代码像样的多。与其花时间编写解释你搞出的糟糕的代码的注释,不如花时间清洁那堆糟糕的代码。

4.2 用代码来阐述

有时,代码本身不足以解释其行为。不幸的是,许多程序员据此以为,代码很少——如果有的话——能做好解释工作。这种观点纯属错误。只要想上那么几秒钟,就能用代码解释你大部分的意图。

很多时候,简单到只需要创建一个描述与注释所言同一事物的函数即可。

//愿意看到这个
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) &&(employee.age > 65))
//还是这个?
if (employee.isEligibleForFullBenefits())

4.3 好注释

有些注释是必须的,也是有利的。来看看一些我认为值得写的注释。不过要记住,唯一真正好的注释是你想办法不去写的注释。

4.3.1 法律信息

有时,公司代码规范要求编写与法律有关的注释。“// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.”

4.3.2 提供信息的注释

有时,用注释来提供基本信息也有其用处。

// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");

4.3.3 对意图的解释

有时,注释不仅提供了有关实现的有用信息,而且还提供了某个决定后面的意图。

4.3.4 阐释

有时,注释把某些晦涩难明的参数或返回值的意义翻译为某种可读形式,也会是有用的。通常,更好的办法是尽量让参数或返回值自身就足够清楚;但如果参数或返回值是某个标准库的一部分,或是你不能修改的代码,帮助阐释其含义的代码就会有用。

4.3.5 警示

有时,用于警告其他程序员会出现某种后果的注释也是有用的。

/**
 * Autogenerated by Thrift Compiler (0.8.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */

//code
......

4.3.6 TODO注释

  • 有时,有理由用//TODO形式在源代码中放置要做的工作列表。

  • TODO是一种程序员认为应该做,但由于某些原因目前还没做的工作。它可能是要提醒删除某个不必要的特性,或者要求他人注意某个问题。

  • 它可能是恳请别人取个好名字,或者提示对依赖于某个计划事件的修改。无论TODO的目的如何,它都不是在系统中留下糟糕代码的借口。

  • 大多数好的IDE都提供了手段来定位所有的TODO注释,这些注释看来丢不了。你不会愿意代码因为TODO的存在而变成一堆垃圾,所以要定期查看,删除不再需要的。

4.3.7 放大

注释可以用来放大某种看起来不合理之物的重要性。

String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));

4.3.8 公共API中的Javadoc

没有什么比被良好描述的公共API更有用和令人满意的了。标准Java库中的Javadoc就是一例。没有它们,写Java程序就会变得很难。

4.4 坏注释

大多数注释都属此类。通常,坏注释都是糟糕的代码的支撑或借口,或者对错误决策的修正,基本上等于程序员自说自话

4.4.1 喃喃自语

如果只是因为你觉得应该或者因为过程需要就添加注释,那就是无谓之举。如果你决定写注释,就要花必要的时间写出好的注释。

4.4.2 多余的注释

如果读注释花的时间比读代码的长,那么这里的注释就太糟糕了。

4.4.3 误导性注释

4.4.4 循规式注释

所谓每个函数都要有Javadoc或每个变量都要有注释的规矩是愚蠢可笑的。这类注释徒然让代码变得散乱,满口胡言,令人迷惑不解。

4.4.5 日志式注释

  • 在模块开始处添加一条注释。这类注释就像是一种记录每次修改的日志。

  •  很久以前,在模块开始处创建并维护这些记录还算有道理。那时,我们还没有源代码控制系统可用。如今,这种冗长的记录只会让模块变得凌乱不堪,应当全部删除。

4.4.6 废话注释

这类注释废话连篇,我们都学会了视而不见。读代码时,眼光不会在它们上面停留。最终,当代码修改之后,这类注释就变作了谎言一堆。

4.4.7 可怕的废话

仔细阅读下面例子注释,你会发现剪切-粘贴错误。作者在写(或粘贴)注释时都没花心思,怎么指望读者从中获益呢?

** The name. */

private String name;

/** The version. */

private String version;

/** The licenceName. */

private String licenceName;

/** The version. */

private String info;

4.4.8 能用函数或变量时就别用注释

// does the module from the global list <mod> depend on the
// subsystem we are part of?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))
//可以改成以下没有注释的版本:
ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))

4.4.9 位置标记

如果标记栏不多,就会显而易见。所以,尽量少用标记栏,只在特别有价值的时候用。如果滥用标记栏,就会沉没在背景噪音中,被忽略掉。如:

// Actions //

4.4.10 括号后面的注释

  • 有时,程序员会在括号后面放置特殊的注释,尽管这对于含有深度嵌套结构的长函数可能有意义,但只会给我们更愿意编写的短小、封装的函数带来混乱。

  • 如果你发现自己想标记右括号,其实应该做的是缩短函数。

4.4.11 归属与署名

  • 源代码控制系统非常善于记住是谁在何时添加了什么。没必要用那些小小的签名搞脏代码。

  • 你也许会认为,这种注释大概有助于他人了解应该和谁讨论这段代码。不过,事实却是注释在那儿放了一年又一年,越来越不准确,越来越和原作者没关系。

  • 重申一下,源代码控制系统是这类信息最好的归属地。

4.4.12 注释掉的代码

同上,源代码控制系统可以取代对代码的注释掉,前者可以为我们记住不要的代码。我们无需再用注释来标记,删掉即可。

4.4.13 HTML注释

IDE中的代码本来易于阅读,却因为HTML注释的存在变得难以卒读。

4.4.14 非本地信息

如果你一定要写注释,请确保它描述了离它最近的代码。别在本地注释的上下文环境中给出系统级的信息。

4.4.15 信息过多

别在注释中添加有趣的历史性话题或者无关的细节描述。

4.4.16 不明显的联系

注释及其描述的代码之间的联系应该显而易见。如果你不嫌麻烦要写注释,至少让读者能看着注释和代码,并且理解注释所谈何物。

4.4.17 函数头

 短函数不需要太多描述。为只做一件事的短函数选个好名字,通常要比写函数头注释要好。

4.4.18 非公共代码中的Javadoc

虽然Javadoc对于公共API非常有用,但对于不打算作公共用途的代码就令人生恶了。

上一篇:JAVA学习笔记02-注释、标识符、关键字以及数据类型


下一篇:java关于文档注释的一些笔记