目录一、注释二、方法长度三、命名四、完整规范五、规则文件给智能体用的 Java 编码规范把注释、方法长度、字段名写成能执行的限制。按 阿里巴巴 Java 开发手册 整理可以直接贴进规则文件。一、注释类和 public 方法写 Javadoc写参数约束、返回值、会不会为 null、会抛什么异常。能从代码看出来的不要写。注释掉的废代码直接删。TODO 带上名字、日期和要做什么。注释用中文名字用英文。二、方法长度单个方法不超过 80 行加上注释也不要超过 100 行。参数不超过 5 个超过 3 个就抽对象。if、for、try套在一起不超过 3 层。单行不超过 120 字符。新类尽量控制在 800 行以内。超出就拆方法不要在原方法里继续加。三、命名类名 UpperCamelCase分层后缀跟仓库走Controller、Service、Mapper。方法名 lowerCamelCaseget / list / page 查create / update / delete 写。字段和局部变量 lowerCamelCase不要a、tmp、data、flag。常量 UPPER_SNAKE。DO、DTO、VO 里的布尔属性不要叫isSuccess用success、deleted。Getter 可以是isDeleted()。表字段user_idJava 写成userId。同一模块里 List 叫orders还是orderList选一种。四、完整规范复制到仓库根目录AGENTS.md。Cursor 放到.cursor/rules/java-backend.mdc。项目里已有 Checkstyle 的以项目配置为准。# Java 编码规范智能体 Java 8Spring Boot 后端。和 Checkstyle 冲突时听仓库。 ## 1、限制 - 方法不超过 80 行含注释不超过 100 行 - 参数不超过 5 个超过 3 个抽参数对象 - if / for / while / try 嵌套不超过 3 层 - 单行不超过 120 字符 - 新类尽量不超过 800 行 - 除 -1、0、1 外数字和业务字符串写成常量。long 用 2L不用 2l - 禁止空 catch。禁止 catch 之后只 printStackTrace或打完日志返回 null - 禁止 System.out.println 打业务日志 - 禁止循环里逐条查库、调 HTTP - 禁止提交编译不过或单测失败的代码 - 集合不要返回 null用 emptyList 或 List.of() - 状态用枚举或常量不要满地 0、1 ## 2、命名 ### 类 - UpperCamelCase用名词。UserOrderService 可以OrderSvc 不行 - 抽象类 Abstract / Base 前缀异常 Exception 后缀测试类加 Test - 后缀跟仓库Controller、Service、ServiceImpl、Mapper、Repository、Config - 对象后缀跟仓库Entity / DO、DTO、VO、Query、BO。不要自造 XxxInfo、XxxData - 不要拼音类名 ### 方法 - lowerCamelCasecreateOrder、listUnpaidOrders、existsByUserId - 查询用 get、list、page、count、exists - 写入用 create、update、delete。插入和更新都可能时才用 save - 转换用 toXxx、fromXxx - 返回 boolean 用 hasXxx、isXxx、canXxx ### 字段 - lowerCamelCase。不要 a、tmp、data、obj、flag。循环下标 i、j、k 除外 - 不要拼音orderId不要 dingdanId - 不要 strName、iCount 这种前缀 - List 在同一模块里统一用 orders 或 orderList - Map 用 orderById - 数组写成 int[] counts - 常量 MAX_RETRY_COUNT - DTO 布尔字段用 deleted、enabled、success不要 isXxx 当字段名 - 列名 user_id 对应字段 userId - 不要 extra1、value2、param ### 包 - 全小写不要下划线 - 按业务分包例如 com.xxx.order.service ## 3、注释 - 类上写这个类干什么 - public 方法写参数、返回值、异常、空值怎么处理 - 枚举每个值写一句 - 正则、补偿、幂等写原因 - TODO 格式TODO 姓名 日期 做什么 - 不要写 // 设置名称 然后 setName - 不要留注释掉的代码 - author、date 仓库里同类有再写不要编工号 java /** * 按用户查询未支付订单。 * userId 为空时返回空列表。 * * param userId 用户主键允许为 null * return 未支付订单不为 null */ public ListOrder listUnpaidByUserId(String userId) { if (!StringUtils.hasText(userId)) { return Collections.emptyList(); } return orderMapper.listByUserIdAndStatus(userId, OrderStatus.UNPAID); } /** 逻辑删除true 表示已删除 */ private Boolean deleted; ## 4、方法 - 一个方法做一件事 - 先校验不行就返回少套 else - 业务放 Service不要塞进实体 - lombok 可以生成 getter / setter。业务流程不要写在实体里 - 找不到数据时一个模块里 Optional 和 null 不要混用 ## 5、分层 - Controller 只做校验、调 Service、返回 VO不写业务不直接注入 Mapper - Service 管事务和规则。跨模块调对方 Service不要调别人 Mapper - Mapper 只访问本模块表 - Controller 不要互调Service 不要调 Controller - 新接口用 DTO / VO不要把 Entity 直接给前端。老接口先不动 ## 6、异常和日志 - 业务失败抛业务异常带错误码和 id - catch 之后要么继续抛要么补偿。不要吞掉 - 日志用 SLF4J{} 占位不要字符串拼接 - 正常路径 INFO异常 ERROR 带堆栈。循环里不要打 INFO - 日志里不要有密码、token、身份证 - 不要 e.printStackTrace() java log.info(创建订单完成, userId{}, orderId{}, userId, order.getId()); log.error(扣减库存失败, skuId{}, orderId{}, skuId, orderId, ex); ## 7、并发 - 线程池用项目里现成的。不要 Executors.newCachedThreadPool - 锁范围尽量小持锁时不要调远程 - 流和连接用 try-with-resources - 时间用 java.time。SimpleDateFormat 不要当成员变量共享 ## 8、Spring - 新代码构造器注入不要字段 Autowired。老类已经是字段注入、只改几行就跟着原文件 - 配置用 ConfigurationProperties不要满类 Value - Transactional 放在 Service 的 public 方法上。this.xxx() 调同类 private事务不会生效 - 只读查询可以用 Transactional(readOnly true) - 新接口路径按资源划分。不要再加一个什么都干的 POST ## 9、测试 - 改了分支就补单测 - 单测不要打外网 - 测试方法不要互相依赖顺序 - 只改这次需要的文件不要顺手格式化整个文件、升级依赖 - 新依赖先看仓库里有没有现成的 - 改完要能编译 ## 10、冲突 - 缩进、lombok、包结构跟着当前改的文件 - 80 行、3 层嵌套、5 个参数、空 catch、魔法值、布尔字段不加 is 前缀这几条不要破 - 和仓库检查工具冲突时听仓库回复里说明一下 ## 11、反例 - public Map process(Map map) 写两百行 - String flag 1 - catch (Exception e) {} - 同一条链路里 user_Name、UserID、userid 混用 - // 增加用户 然后 addUser - if 里套 for 再套 try第四层还不拆 - 字段名叫 isSuccess - System.out.println(order)五、规则文件Cursor 把上一节存成.cursor/rules/java-backend.mdc文件头加上--- description: Java 后端编码规范 globs: **/*.{java,xml} alwaysApply: false ---alwaysApply用false改 Java 时才带上。每次对话都要带再改成true。其他工具读AGENTS.md的放到仓库根目录。写进仓库之后用 Checkstyle 或 IDEA 的 Alibaba 插件扫一遍插件说明见 p3c。规则文件和插件的数字不一致时改规则文件去对齐插件。