| name | code-comment-style |
| description | Use when writing, refactoring, reviewing, or documenting code where comments should be improved. Prefer structured, intent-focused comments with Chinese business-context style when appropriate, including section headers for major phases, professional tags for risks/performance/business constraints, Javadoc for public methods in Controller/Service/ServiceImpl classes, and concise call-site notes before important private helper method calls inside long public methods. Avoid noisy comments that only repeat syntax. |
Code Comment Style
目标:让代码注释像一份“小型交接文档”,人和 AI 下次读到时能快速理解业务意图、风险点和不能乱改的地方。
核心风格
优先写“为什么”和“这里有什么坑”,而不是复述“代码在做什么”。
推荐风格:
- 用分段标题标出主流程。
- 允许使用短标题标签概括当前代码块职责,例如“【发送】统一处理”“【权限预校验】收件人视角”。
- 用短注释解释关键业务规则、当前视角或当前分支的业务语义。
- 使用专业标签提醒维护者,例如“注意”“性能说明”“业务规则”“兼容性说明”“副作用说明”。
- 对公共方法、复杂校验、批处理、查重、缓存、状态回写写清楚输入、输出和副作用。
- 编号只用于同一个方法内部的连续步骤,跨方法不要硬套 1/2/3。
- 长 public 方法里每个关键 private 调用点前,都要写一句“这一步的业务目的”。
- Controller 的 public 接口也要写 Javadoc,说明接口用途、关键参数、返回结果和副作用。
- 不给简单赋值、普通 getter/setter、显而易见的 if/for 贴废话注释。
什么时候必须补注释
看到下面场景时,主动补关键注释:
- 复杂业务校验、逐级断言、状态流转。
- 为了前端展示、SQL 分组统计、后续批处理而写的特殊字段。
- 清空旧值、强制置空、绕过默认 ORM 策略等容易被误删的关键逻辑。
- 本地缓存、批量分组、查重、重试、锁、并发、性能优化。
- 复杂 SQL、动态 SQL、非直观 join、数据修复脚本。
- 日期时间、编码、路径、代理、操作系统差异、兼容性处理。
- 外部接口、第三方服务、文件导入导出、权限差异。
- AI 或维护者很可能“看起来能简化,其实不能简化”的代码。
- Controller 对外暴露的 public 接口,尤其是导入、生成、下发、审核、删除、状态变更类接口。
- 长 public 方法中调用多个 private 小方法的位置,必须解释每个调用对应的业务步骤。
- 事务边界、幂等性、重复提交、并发锁、数据一致性、权限口径、异常兜底。
- 和前端字段、导出模板、第三方接口、历史数据兼容有关的逻辑。
- 明显存在“发件人视角 / 收件人视角 / 管理员视角 / 当前用户视角”这类口径切换的逻辑。
- 存在“普通逻辑 / 管理员逻辑 / 定时逻辑 / 即时逻辑 / 转发逻辑”这类业务分叉的代码。
- 递归查询、树组装、链路回溯、结果汇总、通知补发这类容易迷路的组装型逻辑。
推荐注释模板
1. 主流程分段
适合长方法、导入流程、校验流程、订单状态流转。
编号规则:
- 同一个长方法内部存在明确顺序步骤时,可以使用
1/2/3。
- 不同 public 方法、不同入口方法之间不要连续编号,避免误导读者以为它们属于同一条执行链。
- 跨方法注释应使用“学生视角”“业务口径”“统计口径”这类无编号标题。
推荐:
不推荐:
public void analyzeCourseSelection(...) { ... }
public Report getCourseSelectionReport(...) { ... }
2. 注意说明
适合容易被未来维护者误删的关键逻辑。
3. 业务标题 / 视角标题
适合在方法、代码块、分支前快速说明“当前在处理哪一类业务”。
要求:
- 标题要短,读一眼就知道这段代码在干什么。
- 标题更适合概括“这一段的职责”,不要复述每一行代码。
- 可以带“视角”“口径”“阶段”等词,但不要堆太多修饰语。
4. 性能说明
适合缓存、批量处理、避免数据库 IO 的逻辑。
5. 业务规则
适合“为什么必须这样判断”的业务规则。
6. 副作用说明
适合会回写实体、改变状态、影响前端展示或统计的逻辑。
7. 数据一致性说明
适合事务、状态回写、批量更新、重复提交和幂等处理。
8. 兼容性说明
适合历史数据、旧模板、旧前端字段、第三方接口差异。
9. 异常兜底说明
适合 catch 分支、默认返回、降级逻辑。
10. 权限口径说明
适合不同角色、不同组织、不同数据范围的过滤逻辑。
11. 逻辑分叉说明
适合在 if/else、角色分流、状态分流前,用一句话说明“为什么这里要分两条路走”。
if (isAdmin(currentUserId)) {
...
} else {
...
}
if (Boolean.TRUE.equals(dto.getScheduled()) && dto.getPublishTime() != null) {
...
} else {
...
}
12. 预校验说明
适合方法开头先做权限、状态、前置条件检查的场景。
这类注释的目标是让维护者一眼看出:
- 后面主流程开始前,先挡掉哪些非法状态。
- 为什么这些判断必须放在最前面。
13. 核心组装说明
适合树结构拼装、链路回溯、结果汇总、通知补发、分组聚合这类“读代码容易迷路”的逻辑。
14. 长方法中的 private 调用点说明
如果一个 public 方法较长,并且连续调用多个 private 小方法,不要只给 private 方法本身写注释。
在调用点也要写一句,说明这一步在当前业务流程里的作用。
推荐:
List<StudentScoreSummary> summaries = buildClassScoreSummaries(students);
saveScoreSnapshots(examId, summaries, currentUserId);
不推荐:
buildClassScoreSummaries(students);
saveScoreSnapshots(examId, summaries, currentUserId);
15. 方法级总述说明
如果一个 public 方法承担的是完整业务动作,除了 Javadoc,还可以在方法体开头补一句短总述,帮助读者快速建立上下文。
推荐:
public void sendNotice(NoticeSendDTO dto) {
...
}
适用条件:
- 方法名本身不能完整表达业务上下文。
- 同一个方法要兼容多种入口、多种模式或多种视角。
- 方法较长,读者需要先知道“这整个方法在做什么”。
Javadoc 风格
Controller 接口、Service 接口、ServiceImpl 的 public 方法、复杂私有方法建议写 Javadoc。
不要只在 ServiceImpl 写 Javadoc。Controller 是外部入口,读代码时经常会先从 Controller 追到 Service,因此 Controller 的 public 方法也应该说明接口语义。
写清楚:
- 方法解决什么业务问题。
- 参数是否允许为空。
- 返回值代表什么。
- 是否会修改入参对象或回写状态。
- Controller 方法还要写清楚:接口面向哪个页面/动作、是否会触发状态变更、是否会产生导入/生成/下发等副作用。
- ServiceImpl 的 public 方法如果承担完整业务动作,Javadoc 和方法体开头的短总述可以同时存在:Javadoc 解释边界,方法内短总述解释当前业务角色。
示例:
Controller 示例:
注释语言
- 业务系统、排障文档、中文团队项目:优先中文注释。
- 开源库、英文既有项目:沿用英文注释。
- 文件里已有明确风格:跟随原风格,不强行切换语言。
不要这样写
避免这种只复述语法的注释:
item.setValidationStatus(1);
如果状态值本身不直观,应该写成:
item.setValidationStatus(1);
修改代码时的执行规则
- 新增复杂逻辑时,同步补关键注释。
- 改动已有逻辑时,检查附近注释是否已经过期。
- 发现误导性注释时,优先更新或删除。
- 如果补注释后仍然感觉“偏少”,优先检查 Controller public 方法、长 public 方法调用点、状态回写处、异常分支是否漏写。
- 不为了“显得注释多”而堆注释,但宁可多写一句业务目的,也不要让读者反复跳转 private 方法猜流程。
- 注释要能帮助未来 AI agent 继续排查、修改或验证。
- 优先补“入口总述 + 分段标题 + 关键分支语义 + 调用点目的”这一整套,不要只零散补一两句。