Skip to content

注释规范 ​

TIP

规定后端代码中注释的写法、粒度与维护要求,适用于 Spring Boot 3 + MyBatis-Plus 技术栈。注释使用中文书写,代码标识符仍遵循 命名规范。

设计原则 ​

原则说明
解释 Why,而非 What注释说明意图、约束、边界条件,不重复代码字面含义
保持同步修改逻辑时同步更新注释,过期注释比没有注释更有害
适度精简能靠清晰命名表达的不写注释;复杂逻辑才写
公开 API 必文档化对外暴露的接口、Service 方法需完整说明(Knife4j)
禁止无意义注释不写「定义变量」「调用方法」等显而易见的内容

注释类型 ​

类型语法适用场景
单行注释//简短说明、行内补充
多行注释/* ... */禁止使用,优先用多个 // 或 Javadoc
文档注释/** ... */(Javadoc)类、方法、接口、重要字段
标记注释TODO / FIXME / NOTE待办、缺陷、重要说明

何时写 / 不写 ​

✅ 应该写注释 ​

  • 复杂业务规则、计算公式、状态流转
  • 非显而易见的 workaround、兼容性处理
  • 对外暴露的 API(Controller 接口、Service 方法)
  • 魔法数字、枚举值的业务含义
  • 安全、权限、性能相关的设计决策
  • SQL 条件拼接逻辑

❌ 不应写注释 ​

java
// ❌ 重复代码含义
// 获取用户列表
List<SysUserPO> users = sysUserMapper.selectList(wrapper);

// ❌ 注释掉的废弃代码(应直接删除,由 Git 追溯)
// List<SysUserPO> oldList = oldMethod();

// ❌ 与实现不一致的过期注释
// 仅管理员可访问(实际已改为角色权限校验)

WARNING

禁止提交大段被注释掉的代码。若需保留参考,在 PR 描述或文档中说明,不要留在源码中。

Javadoc 规范 ​

类注释 ​

java
/**
 * <p>系统用户控制器</p>
 *
 * @author Karl <karl_wn@126.com>
 * @since 2021/12/1
 */
@Tag(name = "admin-sysuser")
@RestController
@RequestMapping("/sysuser/")
public class SysUserController {

方法注释 ​

java
/**
 * <p>查询用户信息</p>
 *
 * @param params 查询条件参数
 * @Return: com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map<java.lang.String, java.lang.Object>>
 * @Since: 2022/7/1
 */
@Operation(summary = "查询->全部用户信息", description = "查询全部用户信息")
@PostMapping(value = "/findUsers")
public IPage<Map<String, Object>> findUsers(@RequestBody String params) {

字段注释 ​

java
/**
 * 系统用户服务
 */
@Resource
private SysUserService sysUserService;

/**
 * 厂端用户级别集合
 */
private static final Set<Integer> FACTORY_SET = Set.of(
        100701, 100702, 100703, 100704, 100705, 100706, 100709, 100710
);

OpenAPI 注解(Knife4j) ​

Controller 接口需添加 OpenAPI 注解,自动生成 API 文档:

java
@Tag(name = "admin-sysuser")                    // 接口分组
@Operation(summary = "查询->全部用户信息")       // 接口标题
@Parameter(description = "查询条件参数", required = true)  // 参数说明
注解用途
@Tag(name = "admin-xxx")接口分组(对应 Knife4j 菜单)
@Operation(summary = "...")接口标题与描述
@Parameter(description = "...")请求参数说明

行内注释 ​

业务逻辑说明 ​

java
// 后端 status 为字符串枚举,需转换为前端识别的整数
Integer statusCode = statusMap.get(user.getStatusLabel());

// 兼容旧版本:部分用户 deptId 为 null,需降级为默认部门
if (user.getDeptId() == null) {
    user.setDeptId(DEFAULT_DEPT_ID);
}

分步说明(复杂流程) ​

java
private void processUserImport(List<UserImportVO> list) {
    // 1. 校验必填字段
    validateRequiredFields(list);

    // 2. 转换部门名称为 ID(前端传名称,后端存 ID)
    convertDeptNamesToIds(list);

    // 3. 批量插入用户
    batchInsertUsers(list);
}

单行注释 ​

  • // 后加一个空格
  • 注释放在被说明代码上方,而非行尾
java
// ✅
// 最大重试 3 次,间隔由配置中心统一控制
retryExecutor.execute(task, 3);

String name = user.getName(); // ❌ 仅当行尾注释足够短且必要时才使用

标记注释 ​

标记含义要求
TODO计划中的功能或优化明确说明任务内容及关联
FIXME已知缺陷或临时方案需说明原因与修复计划
NOTE重要提醒,易被人忽略解释非显而易见的约束
HACK不得已的 workaround必须说明原因与移除条件
java
// TODO(#1234): 接入真实导出接口,当前为 Mock 数据
// FIXME: 批量插入超过 1000 条时性能下降,待优化分批逻辑
// NOTE: 该字段只读,后端不允许通过此接口修改
// HACK: 第三方 SDK 未暴露异步方法,仅能用同步调用包装

WARNING

TODO / FIXME 不得长期遗留;每个迭代应清理或转为正式任务。

SQL 注释 ​

动态 SQL 拼接处需加注释说明条件含义:

java
public static String findUsers(Page page, String conditions) {
    StringBuffer sql = new StringBuffer();
    sql.append(" select ");
    sql.append(" 	u.id, ");
    sql.append(" 	u.account, ");
    sql.append(" 	u.user_name userName, ");   // 驼峰别名,方便前端直接使用
    sql.append(" from ");
    sql.append(" 	sys_user u ");
    sql.append(" 	left join sys_dept d on d.id = u.dept_id ");  // 关联部门获取部门信息
    sql.append(" where ");
    sql.append(conditions);
    sql.append(" and u.del_flag = 0 ");  // 软删除过滤
    return sql.toString();
}

反例与正例 ​

重复代码含义 ​

java
// ❌ 无意义注释
// 查询用户
List<SysUserPO> list = sysUserMapper.selectList(wrapper);

// ✅ 命名已足够清晰,无需注释
List<SysUserPO> list = sysUserMapper.selectList(wrapper);

// ✅ 复杂逻辑才需要注释
// 需同时查询主部门和上级部门,用于前端部门树展示
List<SysDeptPO> deptTree = buildDeptTree(userId);

文档完整性 ​

java
// ❌ 对外导出但无 Javadoc
@PostMapping("/findUsers")
public IPage<Map<String, Object>> findUsers(@RequestBody String params) {

// ✅ 完整 Javadoc + OpenAPI 注解
/**
 * <p>查询用户信息</p>
 *
 * @param params 查询条件参数
 * @Return: 分页用户列表
 * @Since: 2022/7/1
 */
@Operation(summary = "查询->全部用户信息", description = "查询全部用户信息")
@PostMapping("/findUsers")
public IPage<Map<String, Object>> findUsers(@RequestBody String params) {

注释 Checklist ​

提交代码前自查:

  • 类有 Javadoc 注释(@author、@since)
  • 对外 API(Controller 接口)有 Javadoc 和 OpenAPI 注解
  • 复杂业务逻辑有「为什么」层面的注释
  • 无重复代码含义的无用注释
  • 无大段注释掉的废弃代码
  • TODO / FIXME 带有任务编号或修复计划描述
  • 修改逻辑后已同步更新相关注释

相关规范 ​