---
trigger: always_on
---
# 后端Java编码规范
## 命名规则
- 类名:大驼峰 UpperCamelCase,名词或名词短语,如 `UserService`, `OrderController`
- 方法名:小驼峰 lowerCamelCase,动词或动词短语,如 `findUserById()`, `createOrder()`
- 查询列表方法:`query` 开头,如 `queryFactoryElectricianMasterRecord()`,禁止用 `get` 开头
- 查询单个方法:`find` 开头,如 `findFactoryElectricianMasterEntityByDataKey()`,禁止用 `get` 开头
- 事务方法:`trans`/`tx` 后缀,如 `saveTemplateTrans()`, `enableTemplateTrans()`, `deleteTemplateTrans()`
- 构建实体方法:`build` 开头,如 `buildXxxEntity()`, `buildXxxVO()`
- 常量名:全大写+下划线,如 `MAX_THREAD_COUNT`, `CACHE_EXPIRE_TIME`
- 局部/成员变量:小驼峰,禁止 `m_`/`_` 前缀
- 布尔变量:以 `is`/`has`/`can` 开头,如 `isDeleted`, `hasPermission`
- 数组/集合:复数形式,List用集合词,Map用map,如 `List<User> userList`, `String[] fileNames`
- DTO/VO/POJO:意义明确的名称,在包结构中区分,如 `UserQueryDTO`, `OrderVO`
- 聚合根命名:以 `Agg` 结尾,如 `AiOutboundCallAgg`, `FactoryElectricianOrderAgg`
- Service接口命名:无前缀I,如 `AiOutboundCallService`(老模块有IFactory前缀)
- Store接口命名:以 `Store` 结尾,如 `CollectionLetterTemplateStore`
## 代码格式
- 使用4个空格缩进,禁止使用Tab键
- 单行字符数不超过120个,超出必须换行
## OOP规则
- 覆写父类方法必须加 `@Override` 注解
- 使用 equals() 比较对象时,必须用常量或确定非空的对象调用,如 `"test".equals(variable)`
## 控制语句
- `if/else/for/while/do` 必须使用大括号,即使只有一行代码
- 采用卫语句形式避免 if-else 过深,代码难以维护
- 禁止在条件判断中执行复杂语句,应赋值给有明确意义的布尔变量
- 循环嵌套不要超过三层
## 注释规范
- 类、类属性、类方法的注释必须使用 Javadoc 规范 `/** ... */`
- 所有抽象方法(含接口方法)必须用 Javadoc 注释
- 代码修改时,注释也要同步修改
## 异常处理
- 项目使用两种自定义异常:
- `FebsException`(checked exception):用于业务校验失败、资源不存在等可预期场景
- `BizException`(unchecked, RuntimeException):用于不可恢复的系统级业务异常
- 禁止捕获异常后什么都不做(空catch块是魔鬼)
- 捕获异常是为了处理它,不想处理就抛给调用者
- finally块必须关闭资源对象、流对象,有异常也要 try-catch
- 异常抛出应尽量考虑周全,宁愿多写代码也不要少写
- Store层不存在时抛异常:`throw new FebsException("当前记录不存在!")`
- **Controller层异常处理策略**:声明 `throws FebsException` 由全局异常处理器统一捕获并返回 `RestResponse.error()`,Controller禁止手动 catch 业务异常
## 消除魔数
- 禁止直接使用魔法数字表示状态等类型,必须使用枚举或常量替代
- 错误:`if (status == 1) { ... }`
- 正确:`if (status == OrderStatus.COMPLETED) { ... }`
## 枚举类规范
- 使用 `@Getter` + 全参构造方法(不用 `@Data`)
- 状态枚举统一 `code` + `name` 字段模式
```java
@Getter
public enum OutboundStatusEnum {
PUSHING(1, "推送中"),
REPEAT(2, "重复");
private Integer code;
private String name;
OutboundStatusEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public static OutboundStatusEnum toEnum(Integer code) {...}
}
```
- 权限枚举使用 String 类型 code:`private String code; private String name;`
## 类职责单一
- Controller层:禁止添加业务查询和过多业务处理,仅负责API映射
- Service层:专注业务处理和参数校验,业务代码和查询代码不混在一起,查询代码放在Store层
- Store层:数据储存层,负责数据查询
- Mapper层:数据库操作
- 通用:类应保持单一职责,避免过于臃肿(如不同业务混在同一个类中应拆分)
## Entity编码规范
```java
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("factory_xxx")
@ApiModel(value = "XxxEntity对象")
public class XxxEntity implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "业务字段")
@TableField("business_field") // 每个字段必须显式指定列名
private String businessField;
@ApiModelProperty(value = "创建时间")
@TableField("create_time")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty(value = "删除标记")
@TableField("deleted")
private Integer deleted;
public XxxEntity() { super(); }
public XxxEntity(String businessField, ...) { // 全参构造(不含id、createBy等基础字段)
this();
this.businessField = businessField;
...
}
}
```
**关键规则**:
- 每个字段必须用 `@TableField("xxx_yyy")` 显式指定列名
- 主键使用 `@TableId(value = "id", type = IdType.AUTO)`
- 时间字段统一 `LocalDateTime` + `@JsonFormat` + `@DateTimeFormat`
- 逻辑删除字段 `Integer deleted`(0/1)
- `@Accessors(chain = true)` 支持链式调用
- 实现 `Serializable`,声明 `serialVersionUID`
## VO/DTO编码规范
```java
// VO
@Data
@ToString
public class XxxVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
private Long id;
@ApiModelProperty(value = "状态文本回显")
private String statusName; // 关联回显字段
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
public XxxVO() { super(); }
public XxxVO(Long id, ...) { this.id=id; ... } // 全参构造
}
// QueryDTO
@Data
@ToString
public class XxxQueryDTO extends PageBaseDTO implements Serializable {
@ApiModelProperty(value = "客户ID")
private Long customerId;
private Boolean hasExport = false; // 导出标识
}
// DTO
@Data
@ToString
public class XxxDTO implements Serializable {
@ApiModelProperty(value = "业务字段")
private String businessField;
}
```
**关键规则**:
- VO/DTO 使用 `@Data` + `@ToString`,实现 `Serializable`
- QueryDTO 继承 `PageBaseDTO`(含 pageNum=1, pageSize=10)
- VO 可包含关联回显字段(如 `statusName`, `customerName`)
- 时间字段同样加 `@JsonFormat` + `@DateTimeFormat`
## 聚合根(Agg)编码规范
```java
@Getter
@ToString
@ApiModel(value = "Xxx对象")
public class XxxAgg implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String businessField;
// ... 其他业务字段
public XxxAgg create(String businessField, String userKey) {
this.fillingMainData(businessField);
return this;
}
public XxxAgg modify(String businessField, String userKey) {
this.fillingMainData(businessField);
return this;
}
private XxxAgg fillingMainData(String businessField) {
this.businessField = businessField;
return this;
}
public XxxAgg fillingDbId(Long id) {
this.id = id;
return this;
}
public XxxAgg() { super(); }
public XxxAgg(Long id, String businessField, ...) { // 全参构造
this(); this.id = id; this.businessField = businessField; ...
}
}
```
**关键规则**:
- 使用 `@Getter`(**不用 `@Data`、`@Setter`**),通过方法封装属性设置
- `create()` / `modify()` 共用私有 `fillingMainData()` 方法
- `fillingDbId()` 用于 Store 层回填主键
- 返回 `this` 支持链式调用
- 全参构造函数用于 Entity→Agg 的转换
## 复用性原则
- 代码块只用一次可以不关注
- 第二次使用需要注意
- 第三次使用必须抽取为独立方法
## 依赖注入
- 统一使用 `@Autowired` 进行依赖注入
- 特殊场景(hologres模块等)可使用 `@Resource`
## 工具库选择
- 优先使用 Hutool 工具类:`ObjectUtil.isEmpty()`, `CollUtil.isEmpty()`, `StrUtil.isBlank()` 等
- 集合工具:`CollUtil` 优先于 `CollectionUtils`
- 对象工具:`ObjectUtil` 优先于手动判空
## 事务处理
- 含事务操作的方法必须含 `trans`/`tx`,如 `createOrderTrans()`
- 传播行为:默认用 REQUIRED,嵌套事务用 REQUIRES_NEW
- 事务边界:仅在Store层使用 `@DSTransactional`
- 禁止在Controller层和private方法使用事务注解
## 日志规范
- 错误日志必须包含关键参数
- 敏感信息必须脱敏处理
后端Java编码规范
LINgZone22026-08-27 19:58
相关推荐
阿里嘎多学长2 小时前
2026-08-24 GitHub 热点项目精选weixin_399380692 小时前
TongWeb7.0.4.9M11一键安装脚本(by sy)CallFay云起未来2 小时前
AI客服能不能减少人工回复?从重复咨询到人机协同的落地分析我命由我123452 小时前
Android 开发 - 获取当前设备屏幕的旋转角度SLD_Allen2 小时前
Go语言runtime全景Elastic 中国社区官方博客2 小时前
OpenTelemetry Java 扩展:无需分叉 agent 即可自定义追踪不灭的黄金瞳1233 小时前
C语言手写顺序表京东云开发者3 小时前
上游给空、下游拿到 -1,我把故障一直追到了 commons-beanutils 的构造函数