编码规范
(一)命名规约
1.类名、方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:(领域模型 的相关命名)DO / DTO / VO / DAO 等。
2.常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
3.POJO 类中的任何布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。
4.包名统一使用小写。
5.接口类中的方法和属性不要加任何修饰符号。
6枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。
(二) 常量定义
1.long 或者 Long 初始赋值时,必须使用大写的 L,不能是小写的 l。
2.不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。
3.常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包
4.内共享常量、类内共享常量。
5.如果变量值仅在一个范围内变化用 Enum 类。
(三)格式规约
1.单行字符数限制不超过 120 个,超出需要换行,换行时,遵循如下原则: 1) 换行时相对上一行缩进 4 个空格。
运算符与下文一起换行。 方法调用的点符号与下文一起换行。 在多个参数超长,逗号后进行换行。 在括号前不要换行,见反例。
2.方法参数在定义和传入时,多个参数逗号后边必须加空格
3.IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不 要使用 windows 格式。
方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之
间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
(四) 集合处理
1、Map/Set 的 key 为自定义对象时,必须重写 hashCode 和 equals。
2、使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一种情况:list.add("c"); 运行时异常。
第二种情况:str[0]= "gujin"; 那么 list.get(0)也会随之修改。
3、不要在 foreach 循环里进行元素的 remove/add 操作。
4、在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,不然 Arrays.sort,Collections.sort 会报 IllegalArgumentException 异常。说明:
(1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。
(2) 传递性:x>y,y>z,则 x>z。
(3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。
反例:下例中没有处理相等的情况,实际使用中可能会出现异常:
new Comparator
(五) OOP 规约
1、避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成 本,直接用类名来访问即可。
2、所有的覆写方法,必须加@Override 注解。
3、所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。 Integer var=?在-128 至 127
4、关于基本数据类型与包装数据类型的使用标准如下:
所有的 POJO 类属性必须使用包装数据类型。 RPC 方法的返回值和参数必须使用包装数据类型。所有的局部变量推荐使用基本数据类型。
5、定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值。
6、构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。
7、使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无内 容的检查,否则会有抛 IndexOutOfBoundsException 的风险。
8、类成员与方法访问控制从严:
( 1) 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。
( 2) 工具类不允许有 public 或 default 构造方法。
( 3) 类非 static 成员变量并且与子类共享,必须是 protected。
( 4) 类非 static 成员变量并且仅在本类使用,必须是 private。
( 5) 类 static 成员变量如果仅在本类使用,必须是 private。
( 6) 若是 static 成员变量,必须考虑是否为 final。
( 7) 类成员方法只供类内部调用,必须是 private。
( 8) 类成员方法只对继承类公开,那么限制为 protected。
(六) 日期时间
1.日期格式化时,传入 pattern 中表示年份统一使用小写的 y。
说明:日期格式化时,yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year(JDK7 之后
引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的 YYYY
就是下一年。
2. 在日期格式中分清楚大写的 M 和小写的 m,大写的 H 和小写的 h 分别指代的意义。
说明:日期格式中的这两对字母表意如下:
1) 表示月份是大写的 M;
2) 表示分钟则是小写的 m;
3) 24 小时制的是大写的 H;
4) 12 小时制的则是小写的 h。
3. 【获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime()。
说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime 的方式。在 JDK8 中,针对统计时间
等场景,推荐使用 Instant 类。
(七) 注释规约
- 【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑
等的修改。 - 【推荐】在类中删除未使用的任何字段、方法、内部类;在方法中删除未使用的任何参数声明
与内部变量。
3.对于注释的要求:第一、能够准确反映设计思想和代码逻辑;第二、能够描述业务含
义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同
天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看
的,使其能够快速接替自己的工作。
(八) 前后端规约
- 前后端交互的 API,需要明确协议、域名、路径、请求方法、请求内容、状态码、响
应体。
说明:
1) 协议:生产环境必须使用 HTTPS。
2) 路径:每一个 API 需对应一个路径,表示 API 具体的请求地址:
a) 代表一种资源,只能为名词,推荐使用复数,不能为动词,请求方法已经表达动作意义。
b) URL 路径不能使用大写,单词如果需要分隔,统一使用下划线。
c) 路径禁止携带表示请求内容类型的后缀,比如".json",".xml",通过 accept 头表达即可。
3) 请求方法:对具体操作的定义,常见的请求方法如下:
a) GET:从服务器取出资源。
b) POST:在服务器新建一个资源。
c) PUT:在服务器更新资源。
d) DELETE:从服务器删除资源。
4) 请求内容:URL 带的参数必须无敏感信息或符合安全要求;body 里带参数时必须设置 Content-Type。
5) 响应体:响应体 body 可放置多种数据类型,由 Content-Type 头来确定。 - 前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}。
说明:此条约定有利于数据层面上的协作更加高效,减少前端很多琐碎的 null 判断。
正例:errorCode / errorMessage / assetStatus / menuList / orderList / configFlag
反例:ERRORCODE / ERROR_CODE / error_message / error-message / errormessage /
ErrorMessage / msg - 服务端返回的数据,使用 JSON 格式而非 XML。
说明:尽管 HTTP 支持使用不同的输出格式,例如纯文本,JSON,CSV,XML,RSS 甚至 HTML。如果我
们使用的面向用户的服务,应该选择 JSON 作为通信中使用的标准数据交换格式,包括请求和响应。此外,
application/JSON 是一种通用的 MIME 类型,具有实用、精简、易读的特点。 - 【推荐】前后端的时间格式统一为"yyyy-MM-dd HH🇲🇲ss",统一为 GMT。
(九) 异常处理
- 【强制】异常捕获后不要用来做流程控制,条件控制。
说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。 - 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请
将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的
内容。 - 不要在 finally 块中使用 return。
说明:try 块中的 return 语句执行成功后,并不马上返回,而是继续执行 finally 块中的语句,如果此处存
在 return 语句,则在此直接返回,无情丢弃掉 try 块中的返回点。
(十) 日志规约
1.推荐对日志进行分类,如将错误日志和业务日志分开存放,便于开发人员查看,也便于通过日志对系
统进行及时监控。
正例:mppserver 应用中单独监控时区转换异常,如:mppserver_monitor_timeZoneConvert.log
2.在日志输出时,字符串变量之间的拼接使用占位符的方式。
说明:因为 String 字符串的拼接会使用 StringBuilder 的 append()方式,有一定的性能损耗。使用占位符仅
是替换动作,可以有效提升性能。
正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
3. 生产环境禁止直接使用 System.out 或 System.err 输出日志或使用
e.printStackTrace()打印异常堆栈。
说明:标准日志输出与标准错误输出文件每次 Jboss 重启时才滚动,如果大量输出送往这两个文件,容易
造成文件大小超过操作系统大小限制。
4. 异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过
关键字 throws 往上抛出。
正例:logger.error("inputParams:{} and errorMessage:{}", 各类参数或者对象 toString(), e.getMessage(), e);