#命名
【规范】类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外: ( 领域模型的相关命名 )DO / BO / DTO / VO 等。
...
4 ) POJO 是 DO / DTO / BO / VO 的统称,禁止命名成 xxxPOJO 。
#常量
【规范】 不允许任何魔法值( 即未经定义的常量 ) 直接出现在代码中。
反例:
| 信息 |
|---|
String key =” Id # taobao _”+ tradeId; cache . put(key , value); |
#格式规约
【风格】单行太长需换行
【风格】方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
#OOP规约
【效率】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
...
【规范】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。
说明:
| 信息 |
|---|
String str = “a,b,c,,”; String[] ary = str.split(“,”); //预期大于 3,结果是 3 System.out.println(ary.length); |
【规范】当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读。
...
4 )例子:final boolean existed = (file.open(fileName, “w”) != null) && (…) || (…);
#集合处理
【强制】 关于 hashCode 和 equals 的处理,遵循如下规则:
...
【强制】不要在 foreach 循环里进行元素的 remove / add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。
反例:
...
| 信息 |
|---|
List<String> |
...
a |
...
= |
...
new |
...
ArrayList<String>(); |
...
a.add( |
...
“1”); |
...
a.add( |
...
“2”); |
...
for |
...
(String |
...
temp |
...
: |
...
a) |
...
{ |
...
if( |
...
“1”.equals(temp)){ |
...
a.remove(temp); |
...
} } 说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?(java.util.ConcurrentModificationException) |
...
正例: |
...
Iterator<String> |
...
it |
...
= |
...
a.iterator(); |
...
while(it.hasNext()){ |
...
String |
...
temp |
...
= |
...
it.next(); |
...
if(删除元素的条件){ |
...
it.remove(); |
...
} } |
【规范】集合初始化时,尽量指定集合初始值大小。 说明: ArrayList 尽量使用 ArrayList(int initialCapacity) 初始化。 【规范】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。 说明: keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key 所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效 率更高。 如果是 JDK8,使用 Map.foreach 方法。
【强制】高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格: |
| 集合类 | Key | Value | Super | 说明 |
|---|---|---|---|---|
| Hashtable | 不允许为 null | 不允许为 null | Dictionary | 线程安全 |
| ConcurrentHashMap | 不允许为 null | 不允许为 null | AbstractMap | 分段锁技术 |
| TreeMap | 不允许为 null | 允许为 null | AbstractMap | 线程不安全 |
| HashMap | 允许为 null | 允许为 null | AbstractMap | 线程不安全 |
...
【规范】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。
正例:
| 信息 |
|---|
public class TimerTaskThread extends Thread { super.setName(“TimerTaskThread”); |
...
|
【规范】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
...
【规范】HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在 开发过程中注意规避此风险。
#控制语句
【规范】在一个 switch 块内,每个 case 要么通过 break/return 等来终止,要么注释说明程 序将继续执行到哪一个 case 为止;在一个 switch 块内, 都必须包含一个 default 语句并且 放在最后,即使它什么代码也没有。
...
底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一 台服务器中,所以 DAO 的参数校验,可以省略。
被声明成private只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参 数已经做过检查或者肯定不会有问题,此时可以不校验参数。
#注释规约
【规范】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/内容*/格式,不得使用 //xxx 方式。
...
在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。
#异常
【规范】异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
...
【规范】避免出现重复的代码(Don’t Repeat Yourself),即DRY原则。
#日志
【规范】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架
...
思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?
#其它
【效率】 在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。 说明:不要在方法体内定义:Pattern pattern = Pattern.compile(规则);
...
【规范】对于“明确停止使用的代码和配置”,如方法、变量、类、配置文件、动态配置属性等要坚决从程序中清理出去,避免造成过多垃圾。
#单元测试
【强制】好的单元测试必须遵守 AIR 原则。
...