Java开发规范
必须 |
统一类名后缀 01 接口和实现类:
02 POJO类/领域模型(DO/DTO/VO):
03 设计模式:尾部加Factory/Listener/Proxy/Observer/Builder/Handler等 其他:
|
VO:视图对象——controller与前端交互的参数 (View Object) BO:业务对象——Service层封装业务逻辑的对象 (Business Object) 对内 DO:数据对象——与实体类/数据表对应 (Data Object) /DAO/PO DTO:数据传输对象—— Service或Manager向外传输的对象 (Data Transfer Object) 对外 Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。 总:POJO类是DO/DTO/BO/VO的统称。 注:DTO理解为RPC 接口请求/传出的对象,又或者在java内部调用外部 API JSON 解析 的对象。 |
参考 |
常见的包名: entity:模型 dao:访问数据库的接口 manage:通用业务处理层 service:服务层接口 controller:web接口 template:视图层模板 exception:异常 handler:处理类 enums:枚举 constant:常量 request:请求 response:响应 biz:业务 impl:接口实现 util:工具类 |
Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。 Service层:相对具体的业务逻辑服务层。 Manager层:通用业务处理层,它有如下特征: 1) 对第三方平台封装的层,预处理返回结果及转化异常信息; 2) 对Service层通用能力的下沉,如缓存方案、中间件通用处理; 3) 与DAO层交互,对多个DAO的组合复用。 DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase 等进行数据交互。 外部接口或第三方平台:包括其它部门RPC开放接口,基础平台,其它公司的HTTP接口。 |
参考 |
Service/DAO层方法命名规约: 1)获取单个对象的方法用get做前缀。 2)获取多个对象的方法用list做前缀,复数结尾,如:listObjects。 3)获取统计值的方法用count做前缀。 4)插入的方法用save/insert做前缀。 5)删除的方法用remove/delete做前缀。 6)修改的方法用update做前缀 |
|
必须 |
变量驼峰形式(除专有名词)、数据库字段用下划线形式、常量大写且下划线作词义分隔 |
常用命名法:驼峰 addUser 蛇形 add_user 脊柱 add-user |
必须 |
POJO类中的任何布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误。 |
代码规范
必须 |
接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁 性,并加上有效的 Javadoc 注释 |
建议 |
类成员与方法访问控制从严(public/protected/private/package),不要全public |
必须 |
不用的代码要删除,不要注释 |
必须 |
代码中间不能使用魔数(没有声明的值),哪怕仅这一个地方使用 |
必须 |
所有的POJO类属性必须使用包装数据类型 Integer 所有的RPC方法参数及返回值必须使用包装数据类型 Integer 方法内的局部变量使用基本类型 int 方法的入参及返回值用基本类型 int ??? |
POJO:数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险。 RPC:包装数据类型的null值,能够表示额外的信息,如:远程调用失败,异常退出。 |
必须 |
禁止浮点数或双精度数的直接基础运算,运算使用Bigdecimal或转为整型 |
对象使用 |
必须 |
禁止在Service中声明非final字段,除非进行特别并发安全说明 |
|
必须 |
Integer等包装类型比较必须判空;禁止Integer直接和数值比较(比如 Integer i= new Integer(127); i==127)——> 使用Objects.equals(a,b) |
|
必须 |
方法的参数不能超过5个;超过后封装成对象 |
|
必须 |
禁止无界队列和无界数组形式集合 |
|
必须 |
String += 类型操作;累加超过5次以上时;需要考虑转化为StringBuffer或者StringBuilder(现有编译器在无并发情况下会把StringBuffer自动降级转为StringBuilder) |
|
必须 |
构造方法中禁止加入业务逻辑 |
|
建议 |
使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历 |
|
必须 |
使用SimpleDateFormat这种类似的类时,确保做线程安全封装。通过检查类或其父类是否定义了类级非终态字段来初步判断其是否线程安全 |
|
建议 |
防止NPE(空指针异常),做必要的参数判断,int i = IntegerXxx,ArrayUtils.isNotEmpty()等都是NPE常见陷阱 |
必须 |
所有的网络连接和网络读写必须有超时时间设置 |
网络连接 |
必须 |
条件判断要先易后难,先简后繁,率先作无效推定。禁止深层的if嵌套导致的箭头式代码 |
控制语句 |
异常
必须 |
不要通过检查异常类型的方式来进行流程控制。因为异常在传递过程中存在fillStacktrace过程,效率低 |
|
推荐 |
定义时区分unchecked / checked异常,避免直接抛出newRuntimeException(),更不允许抛出Exception或者Throwable,应使用有业务含义的自定义异常。推荐业界已定义过的自定义异常,如:DAOException / ServiceException等。 |
前后端规范
必须 |
在前后端交互的JSON格式数据中,所有的key为小写字母下划线。 |
如 task_id |
必须 |
前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}。 |
说明:此条约定有利于数据层面上的协作更加高效,减少前端很多琐碎的null判断。 |
注释
必须 |
接口和抽象类中的公有方法必须定义注释 类/接口要给出注释 |
|
必须 |
工具类不允许有public或default构造方法 |
日志
必须 |
日志参数必须使用占位符,禁止字符串拼接,示例:logger.error("cost: {}ms, message:{}", cost, message, e) |
|
必须 |
日志统一使用Slf4j |
|
必须 |
应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。 |
|
必须 |
catch住不再上抛的异常,必须打印异常堆栈 |
数据库
必须 |
表的命名最好是加上“业务名称_表的作用” |
|
必须 |
建表时,必须具有表的描述和每个字段的描述信息 |
|
必须 |
所有字段必须声明为NOT NULL,并指定DEFAULT值 |
|
必须 |
小数类型为 decimal,禁止使用 float 和 double |
|
建议 |
单表行数超过 500 万行或者单表容量超过 2GB,推荐进行分库分表 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!