Java 后端开发规范
前言
后端开发中,统一的编码规范能显著提升代码质量和团队协作效率。
本文整理一套简洁通用的 Java 后端开发规范,涵盖命名规范、代码风格、异常处理、项目结构与最佳实践。
适用于 Spring Boot + Java 17+ 技术栈,其他框架可按需调整。
命名规范
常见命名方式
开发中常见的命名风格主要有以下几种,了解它们有助于在不同场景下选择合适的写法。
| 命名方式 | 规则 | 示例 | 常见用途 |
|---|---|---|---|
| PascalCase(大驼峰) | 每个单词首字母大写 | UserService、OrderController |
类名、接口名、枚举名 |
| camelCase(小驼峰) | 首单词小写,后续首字母大写 | userName、getOrderList |
变量、方法名、参数 |
| kebab-case(短横线) | 全小写,单词间用 - 连接 |
user-service、order-detail |
配置 key、URL 路径 |
| snake_case(下划线) | 全小写,单词间用 _ 连接 |
user_name、create_time |
数据库字段 |
| UPPER_SNAKE_CASE(大写下划线) | 全大写,单词间用 _ 连接 |
MAX_COUNT、API_BASE_URL |
常量 |
Java 后端项目中,最常用的是 PascalCase、camelCase 和 snake_case 三种。
类与接口命名
- 类名使用 PascalCase,如
UserService、OrderController。 - 接口名使用 PascalCase,如
UserRepository、Payable。 - 抽象类以
Abstract开头,如AbstractBaseService。 - 实现类以
Impl结尾,如UserServiceImpl。
1 | // 推荐 |
方法命名
- 方法名使用 camelCase,动词开头。
- 查询方法以
get、list开头。 - 新增方法以
add开头。 - 修改方法以
update开头。 - 删除方法以
del开头。 - 判断方法以
is、has、can开头。
1 | // 查询 |
变量与常量命名
- 变量名使用 camelCase,如
userName、createTime。 - 常量使用 UPPER_SNAKE_CASE,如
MAX_RETRY_COUNT、DEFAULT_PAGE_SIZE。 - 布尔变量以
is、has、can开头,如isDeleted、hasPermission。 - 集合变量使用复数形式,如
userList、orderIds。
1 | // 推荐 |
项目结构
推荐目录
1 | src/main/java/com/example/project/ |
分层职责
- Controller 层:接收请求、参数校验、调用 Service、返回响应。
- Service 层:业务逻辑处理、事务管理。
- Repository 层:数据访问、SQL 编写。
- Model 层:数据模型定义。
1 | // Controller 层 |
文件命名
- Controller 类以
Controller结尾,如UserController.java。 - Service 接口以
Service结尾,实现类以ServiceImpl结尾。 - Repository 接口以
Repository或Mapper结尾。 - DTO 类以
Dto结尾,VO 类以Vo结尾。
代码逻辑
- 不要出现单个逻辑让前端判断不同逻辑进行不同业务处理。
代码风格
格式规范
- 使用 4 空格缩进,不使用 Tab。
- 每行不超过 120 个字符,超长时换行对齐。
- 左大括号
{不换行,右大括号}独占一行。 - 方法之间空一行,类内逻辑块之间空一行。
1 | // 推荐 |
注释规范
- 类和接口必须添加 Javadoc 注释,说明用途。
- 公共方法必须添加 Javadoc 注释,说明参数、返回值、异常。
- 复杂逻辑必须添加行内注释,说明意图而非描述代码。
- TODO 注释格式:
// TODO(作者): 说明
1 | /** |
导入规范
- 使用显式导入,禁止使用通配符
import xxx.*。 - 导入顺序:
java.*→javax.*→ 第三方库 → 项目内包。 - 静态导入仅用于常量和工具方法,如
import static org.junit.Assert.*。
1 | // 推荐 |
异常处理
异常定义
- 业务异常继承
RuntimeException,如BusinessException。 - 异常信息使用枚举或常量管理,避免硬编码。
- 异常码使用数字或字符串,便于前端处理。
1 | /** |
错误码
错误码是前后端协作的重要约定,规范的错误码设计能快速定位问题。
错误码格式
推荐使用 模块前缀 + 数字编号 的格式,便于分类和扩展。
1 | 格式:{模块}_{编号} |
错误码分类
| 类型 | 前缀 | 范围 | 说明 |
|---|---|---|---|
| 成功 | SUCCESS |
0 | 请求成功 |
| 系统错误 | SYSTEM |
1xxx | 服务器内部错误、第三方服务异常 |
| 参数错误 | PARAM |
2xxx | 参数校验失败、格式错误 |
| 认证授权 | AUTH |
3xxx | 登录过期、权限不足 |
| 业务错误 | 按模块定义 | 各模块自定义 | 具体业务逻辑异常 |
错误码枚举
使用枚举统一管理错误码,避免硬编码。
1 | public enum ErrorCode { |
统一响应体
定义统一的响应格式,前端可据此判断请求结果。
1 |
|
使用示例
在业务代码中使用错误码枚举抛出异常。
1 | // 业务异常类 |
规范要求
- 错误码必须使用枚举或常量类统一管理,禁止在代码中硬编码。
- 每个模块的错误码前缀不同,便于快速定位问题模块。
- 错误信息要对用户友好,避免暴露技术细节。
- 新增错误码时同步更新枚举类,保持错误码列表完整。
异常抛出
- 业务逻辑异常使用
throw new BusinessException(...)。 - 参数校验异常使用
throw new IllegalArgumentException(...)。 - 不要捕获异常后不处理,至少打印日志。
1 | // 推荐 |
全局异常处理
使用 @RestControllerAdvice 统一处理异常,返回标准响应格式。
1 |
|
代码习惯
跨域
接口中不要写跨域逻辑,跨域在Nginx中处理。
参数校验
使用 @Valid 和 @Validated 注解进行参数校验,配合 JSR 303 注解。
1 | // DTO 定义 |
日志规范
- 使用 SLF4J + Logback 日志框架。
- 日志级别:
ERROR>WARN>INFO>DEBUG。 - 生产环境默认
INFO级别,开发环境可调至DEBUG。 - 日志格式包含时间、级别、类名、方法名、行号。
- 设置日志路径 logs文件夹下。
1 | private static final Logger log = LoggerFactory.getLogger(UserService.class); |
工具类设计
- 工具类使用
final修饰,防止被继承。 - 构造函数私有化,防止实例化。
- 方法使用
static修饰,直接通过类名调用。
1 | public final class StringUtils { |
避免的写法
- 禁止使用
魔法值,统一使用常量定义。 - 禁止在循环中进行数据库查询,应批量查询。
- 禁止在 Service 层直接操作
HttpServletRequest。 - 禁止使用
System.out.println()输出日志。 - 多表关联
- 避免过深的嵌套,超过 3 层时考虑拆分方法。
1 | // 推荐 |
接口文档
- 所有对外接口必须生成文档,不允许存在未文档化的接口。
- 所有接口要有意义,不要有机械式无意义的增删改查。
- 接口按照应用模块而不是表模块进行归类。
- 多端如果有明显差异接口要分开。
- 接口描述必须清晰,说明业务场景和使用注意事项。
- 请求参数必须标注是否必填与类型,提供示例值。
- 响应字段必须说明含义及类型,枚举值需列出可选项。
- 接口变更时同步更新文档,保持文档与代码一致。
- 文档返回值类型和必填要符合实际情况。
- 字段不能缺失,也不能冗。
对其他端要求
原型/设计
原型和设计保持一致
需求变更原型和设计要同步变更