版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。
评论: Migration of unmigrated content due to installation of a new plugin

#命名

【规范】类名使用 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 方法。

Wiki 标记
Map<String, String> map = new HashMap<String, String>();

map.put("1", "@@");

map.put("2", "##");

/

\* JDK8推荐使用

*/

map.forEach((K, V) -> {

    System.out.println("Key : " + K);

    System.out.println("Value : " + V);

});

/

\* foreach推荐使用

*/

for (Map.Entry<String, String> entry : map.entrySet()) {

    System.out.println("Key : " + entry.getKey());

    System.out.println("Value : " + entry.getValue());

}

/

\* 不推荐使用

*/

for (String key : map.keySet()) {

    System.out.println("Key : " + key);

    System.out.println("Value : " + map.get(key));

}

【强制】高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:


集合类KeyValueSuper说明
Hashtable不允许为 null不允许为 nullDictionary线程安全
ConcurrentHashMap不允许为 null不允许为 nullAbstractMap分段锁技术
TreeMap不允许为 null允许为 nullAbstractMap线程不安全
HashMap允许为 null允许为 nullAbstractMap线程不安全

...

【规范】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。

正例:

信息

public class TimerTaskThread extends Thread {
public TimerTaskThread() {

super.setName(“TimerTaskThread”);

...


}
}

【规范】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

...

【规范】HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在 开发过程中注意规避此风险。

#控制语句

【规范】在一个 switch 块内,每个 case 要么通过 break/return 等来终止,要么注释说明程 序将继续执行到哪一个 case 为止;在一个 switch 块内, 都必须包含一个 default 语句并且 放在最后,即使它什么代码也没有。

...

  1. 底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一 台服务器中,所以 DAO 的参数校验,可以省略。

  2. 被声明成private只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参 数已经做过检查或者肯定不会有问题,此时可以不校验参数。

#注释规约

【规范】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/内容*/格式,不得使用 //xxx 方式。

...

在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。

#异常

【规范】异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。

...

【规范】避免出现重复的代码(Don’t Repeat Yourself),即DRY原则。

#日志

【规范】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架

...

思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

#其它

【效率】 在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。 说明:不要在方法体内定义:Pattern pattern = Pattern.compile(规则);

...

【规范】对于“明确停止使用的代码和配置”,如方法、变量、类、配置文件、动态配置属性等要坚决从程序中清理出去,避免造成过多垃圾。

#单元测试

【强制】好的单元测试必须遵守 AIR 原则。

...