一、编程规范
(一)命名规约
1【强制】 POJO 类中布尔类型的变量,都不要加,否则部分框架解析会引起序列化错误。
- 反例:定义为基本数据类型的属性,它的方法也是,RPC 框架在反向解析的时候,“以为”对应的属性名称是,导致属性获取不到,进而抛出异常。
2【推荐】 接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法有关,并且是整个应用的基础常量。
- 正例:接口方法签名 接口基础常量表示为
- 反例:接口方法定义为
- 说明:JDK8 中接口允许有默认实现,那么这个方法,是对所有实现类都有价值的默认实现。
(二)常量定义
1【强制】 不允许出现任何魔法值(即未经定义的常量)直接出现在代码中。
- 反例:
2【强制】 或者初始赋值时,必须使用大写的,不能是小写的,小写容易跟数字混淆,造成误解。
- 说明:写的是,还是型的?
(三)格式规约
1【强制】 任何运算符左右必须加一个空格。
- 说明:运算符包括赋值运算符、逻辑运算符、加减乘除符号、三目运算符等。
2【强制】 方法参数在定义和传入时,多个参数逗号后边必须加空格。
- 正例:无论是参数还是参数后面皆有空格。
(四)OOP规约
1【强制】 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
2【强制】 的方法容易抛空指针异常,应使用常量或确定有值的对象来调用。
- 正例:
- 反例:
- 说明:推荐使用(JDK7 引入的工具类)
3【强制】 所有的相同类型的包装类对象之间值得比较,全部使用方法比较。
- 说明:对于在至之间的赋值,对象是在产生,会复用已有对象,这个区间内的值可以直接使用进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用方法进行判断。
4【强制】 关于基本数据类型与包装数据类型的使用标准为:所有的 POJO 类属性必须使用包装数据类型;RPC 方法的返回值和参数必须使用包装数据类型;所有的局部变量推荐使用基本数据类型。
- 说明:POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显示地进行赋值,任何 NPE 问题,或者入库检查,都是使用者来保证。
- 正例:数据库的查询结果可能是,因为自动拆箱,用基本数据类型接收有 NPE 风险。
- 反例:比如显示成交总额涨跌情况,即正负,为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示,这是不合理的,应该显示成中划线,所以包装数据类型的值,能够表示额外的信息,如远程调用失败,异常退出。
5【强制】 序列化类新增属性时,请不要修改字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改值。
- 说明:注意不一致会抛出序列化运行时异常。
6【推荐】 循环体内,字符串的联接方式,使用的方法进行扩展。
- 反例:
- 说明:反编译出的字节码文件显示每次循环都会出一个。对象,然后进行操作,最后通过方法返回对象,造成内存资源浪费。
7【推荐】 慎用的方法来拷贝对象。
- 说明:对象的方法默认是浅拷贝,若想实现深拷贝需要重写方法实现属性对象的拷贝。
(五)集合处理
1【强制】 关于和的处理,遵循规则:只要重写,就必须重写;因为存储的是不重复的对象,依据和进行判断,所以存储的对象必须重写这两个方法;如果自定义对象作为的键,那么必须重写和。
- 正例:重写了和方法,所以我们可以非常愉快地使用对象作为来使用。
2【强制】 的结果不可强转成 ,否则会抛出异常:
- 说明:返回的是的内部类,并不是,而是的一个视图,对于子列表的所有操作最终会反映到原列表上。
3【强制】 使用工具类把数组转换成集合时,不能使用其修改集合相关的方法,它的方法会抛出异常。
- 说明:的返回对象是一个内部类,并没有实现集合的修改方法。体现的是适配器模式,只是转换接口,后台的数据仍然是数组。
4【推荐】 使用遍历类集合,而不是方式进行遍历。
- 说明:其实是遍历了次,一次是转为对象,另一次是从中取出对应的,而只是遍历了一次就把和都放到了中,效率更高。如果是 JDK8,使用方法。
- 正例:返回的是值集合,是一个集合对象;返回的是值集合,是一个集合对象;返回的是值组合集合。
5【推荐】 高度注意类集合能不能存储值的情况,如下表格:
- 反例:由于的干扰,很多人认为是可以置入值,注意存储值时会抛出 NPE 异常。
(六)并发处理
1【强制】 线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。
- 正例:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。
2【强制】 线程池不允许使用去创建,而是通过的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
- 说明:返回的线程池对象的弊端如下,
- 和,允许的请求队列长度为,可能会堆积大量的请求,从而导致 OOM。
- 和,允许的创建线程数量为,可能会创建大量的线程,从而导致 OOM。
3【强制】 高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。
4【强制】 并发修改同一记录时,避免更新丢失,要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用作为更新依据。
- 说明:如果每次访问冲突概率小于,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于次。
5【强制】 多线程并行处理定时任务时,运行多个时,只要其中之一没有捕获抛出异常,其他任务便会自动终止运行,使用则没有这个问题。
(七)控制语句
1【推荐】 尽量少用,的方式可以改写成:
- 说明:如果非得使用方式表达逻辑,请勿超过 3 层,超过请使用状态设计模式。
- 正例:逻辑上超过 3 层的代码可以使用卫语句,或者状态模式来实现。
2【推荐】 除常用方法(如)等外,不用在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
- 说明:很多语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能确定什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?
- 正例:
- 反例:
(八)注释规约
1【参考】 注释掉的代码尽快要配合说明,而不是简单的注释掉。
- 说明:代码被注释掉有两种可能性, 后续会恢复此段代码逻辑; 永久不用。前者如果没有备注信息,难以知悉注释动机;后者建议直接删掉(代码仓库保持了历史代码)。
2【参考】 特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描,经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。
- 说明 1:待办事宜,表示需要实现,但目前还未实现的功能。这实际上是一个 Javadoc 的标签,目前的 Javadoc 还没有实现,但已经被广泛使用。只能应用于类,接口和方法,原因就在于它是一个 Javadoc 标签。
- 说明 2:错误,不能工作,在注释中用标记某代码是错误的,而且不能工作,需要及时纠正的情况。
(九)其他
1【强制】 后台输送给页面的变量必须加——中间的感叹号。
- 说明:如果或者不存在,那么会直接显示在页面上。
2【强制】 注意这个方法java基础代码编程返回时类型, 注意取值的范围(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将放大的若干倍然后取整,直接使用对象的或者方法。
3【强制】 获取当前毫秒数而不是
- 说明:如果想获取更加精确的纳秒时间值,用。在 JDK8 中,针对统计时间等场景,推荐使用类。
二、异常日志
(一)异常处理
1【强制】 不能在块中使用,块中的返回后方法结束执行,不会再执行块中的 语句。
2【推荐】 防止 NPE 是程序员的基本修养,注意 NPE 产生的场景:
- 返回类型为包装数据类型,有可能是,返回值时注意判空;
- 数据库的查询语句可能为 ;
- 集合里的元素即使,取出的数据元素可能为;
- 远程调用返回对象,一律要求进行 NPE 判断;
- 对于 Session 中获取的数据,建议 NPE 检查,避免空指针。
3【参考】 避免出现重复的代码(Dont’t Repeat Yourself),即 DRY 原则。
- 说明:随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是共用模块。
- 正例:一个类中有多个方法,都需要进行数行相同的参数校验操作,这个时候请抽取,
(二)日志规约
1【强制】 应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
2【强制】 对级别的日志输出,必须使用条件输出形式或者使用占位符的方式。
- 说明:如果日志级别是,上述日志不会打印,但是会执行字符串拼接操作,如果是对象,会执行方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。
- 正例:(条件)
- 正例:(占位符)
- 1
3【推荐】 谨慎地记录日志。生产环节禁止输出日志;有选择地输出日志;如果使用来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志。
- 说明:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?
三、MySQL 规约
(一)建表规约
1【强制】 表名、字段名必须使用小写字母或数字;禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
- 正例:
- 反例:
2【强制】 唯一索引名为;普通索引名则为。
- 说明:即;即的简称。
3【强制】 小数类型为,禁止使用和。
- 说明:和在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过的范围,建议将数据拆成整数和小数分开存储。
4【强制】 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为,独立出来一张表,用主键来对应,避免影响其他字段索引效率。
5【强制】 表必备三字段:,,。
- 说明:其中必为主键,类型为、单表时自增、步长为;和的类型均为类型。
(二)索引规约
1【强制】 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。
- 说明:不用以为唯一索引影响了速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验和控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。
2【强制】 超过三个表禁止。需要的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。
- 说明:即使双表也要注意表索引、SQL 性能。
3【强制】 在字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
- 说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会高达 90% 以上,可以使用的区分度来确定。
(三)SQL规约
1【强制】 不要使用或来替代,就是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
- 说明:会统计值为 NULL 的行,而不会统计此列为 NULL 值的行。
2【强制】 计算该列除 NULL 之外的不会重复数量。注意如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为。
(四)ORM规约
1【强制】 在表查询中,一律不要使用作为查询的字段列表,需要哪些字段必须明确写明。
- 说明:1)增加查询分析器解析成本;2)增减字段容易与配置不一致。
2【强制】 不要用当返回参数,即使所有类属性名与数据库字段一一对应,也需要定义;反过来,每一个表也必然有一个与之对应。
- 说明:配置映射关系,使字段与 DO 类解耦,方便维护。
3【强制】 配置中参数注意使用:,不要使用,此种方式容易出现 SQL 注入。
四、其他
1【强制】 依赖于一个二方库群时,必须定义一个统一版本变量,避免版本号不一致。
- 说明:依赖,它们都是同一个版本,可以定义一个变量来保持版本:,定义依赖的时候,引用该版本。
2【强制】 禁止在子项目的依赖中出现相同的,相同的,但是不同的。
- 说明:在本地调试时会使用各子项目指定的版本号,但是合并成一个,只能有一个版本号出现在最后的目录中。曾经出现过线下调试是正确的,发布到线上出故障的先例。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/20554.html