阿里开发手册细节总结
2018-04-14 21:14:55
916 次阅读
0 个评论
【强制】 POJO 类中布尔类型的变量,都不要加 is ,否则部分框架解析会引起序列化错误。
反例:定义为基本数据类型 Boolean isDeleted;的属性,它的方法也是 isDeleted() , RPC
框架在反向解析的时候,“以为”对应的属性名称是 deleted ,导致属性获取不到,进而抛出异
常。
【强制】不允许任何魔法值( 即未经定义的常量 ) 直接出现在代码中。
反例: String key = " Id #taobao _" + tradeId;
cache . put(key , value);
【强制】 long 或者 Long 初始赋值时,使用大写的 L ,不能是小写的 l ,小写容易跟数字 1 混
淆,造成误解。
说明: Long a = 2 l; 写的是数字的 21,还是 Long 型的 2?
【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
正例:下例中实参的" a ",后边必须要有一个空格。
method("a", "b", "c");
【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。
说明:对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在
IntegerCache . cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行
判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
【强制】 POJO 类必须写 toString 方法。使用 IDE 的中工具: source > generatetoString
时,如果继承了另一个 POJO 类,注意在前面加一下 super . toString 。
说明:在方法执行抛出异常时,可以直接调用 POJO 的 toString() 方法打印其属性值,便于排查问题
【推荐】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无
内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。
说明:
String str = "a,b,c,,";
String[] ary = str.split(",");
// 预期大于 3,结果是 3
System.out.println(ary.length);
【推荐】 final 可以声明类、成员变量、方法、以及本地变量,下列情况使用 final 关键字:
1) 不允许被继承的类,如: String 类。
2) 不允许修改引用的域对象,如: POJO 类的域变量。
3) 不允许被重写的方法,如: POJO 类的 setter 方法。
4) 不允许运行过程中重新赋值的局部变量。
5) 避免上下文重复使用一个变量,使用final 描述可以强制重新定义一个变量,方便更好
地进行重构。
【推荐】集合初始化时,指定集合初始值大小。
说明: HashMap 使用 HashMap(int initialCapacity) 初始化,
正例: initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader
factor)默认为 0.75, 如果暂时无法确定初始值大小,请设置为 16(即默认值)。
【强制】 SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为
static ,必须加锁,或者使用 DateUtils 工具类。
正例:注意线程安全,使用 DateUtils 。亦推荐如下处理:
private static finalThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@ Override
protected DateFormat initialValue() {
return newSimpleDateFormat("yyyy-MM-dd");
}
};
说明:如果是 JDK 8 的应用,可以使用 Instant 代替 Date , LocalDateTime 代替 Calendar ,
DateTimeFormatter 代替SimpleDateFormat ,官方给出的解释: simple beautiful strong
immutable thread - safe 。
【强制】多线程并行处理定时任务时,Timer 运行多个 TimeTask 时,只要其中之一没有捕获
抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService 则没有这个问题。
【参考】 HashMap 在容量不够进行resize 时由于高并发可能出现死链,导致 CPU 飙升,在
开发过程中可以使用其它数据结构或加锁来规避此风险。
【强制】在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
说明:不要在方法体内定义: Pattern pattern = Pattern .compile( 规则 );
【强制】后台输送给页面的变量必须加 $!{var} ——中间的感叹号。
说明:如果 var = null 或者不存在,那么 ${var} 会直接显示在页面上。
【强制】注意 Math . random() 这个方法返回是double 类型,注意取值的范围 0≤ x <1 (能够取到零值,注意除零异常) ,如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后
取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。
【推荐】任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
【强制】小数类型为 decimal ,禁止使用 float 和 double 。
说明: float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不
正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。
【推荐】单表行数超过 500 万行或者单表容量超过 2 GB ,才推荐进行分库分表。
【推荐】 in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内
【强制】不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
【推荐】不要写一个大而全的数据更新接口。传入为 POJO 类,不管是不是自己的目标更新字段,都进行 update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行 SQL
反例:定义为基本数据类型 Boolean isDeleted;的属性,它的方法也是 isDeleted() , RPC
框架在反向解析的时候,“以为”对应的属性名称是 deleted ,导致属性获取不到,进而抛出异
常。
【强制】不允许任何魔法值( 即未经定义的常量 ) 直接出现在代码中。
反例: String key = " Id #taobao _" + tradeId;
cache . put(key , value);
【强制】 long 或者 Long 初始赋值时,使用大写的 L ,不能是小写的 l ,小写容易跟数字 1 混
淆,造成误解。
说明: Long a = 2 l; 写的是数字的 21,还是 Long 型的 2?
【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
正例:下例中实参的" a ",后边必须要有一个空格。
method("a", "b", "c");
【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。
说明:对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在
IntegerCache . cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行
判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
【强制】 POJO 类必须写 toString 方法。使用 IDE 的中工具: source > generatetoString
时,如果继承了另一个 POJO 类,注意在前面加一下 super . toString 。
说明:在方法执行抛出异常时,可以直接调用 POJO 的 toString() 方法打印其属性值,便于排查问题
【推荐】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无
内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。
说明:
String str = "a,b,c,,";
String[] ary = str.split(",");
// 预期大于 3,结果是 3
System.out.println(ary.length);
【推荐】 final 可以声明类、成员变量、方法、以及本地变量,下列情况使用 final 关键字:
1) 不允许被继承的类,如: String 类。
2) 不允许修改引用的域对象,如: POJO 类的域变量。
3) 不允许被重写的方法,如: POJO 类的 setter 方法。
4) 不允许运行过程中重新赋值的局部变量。
5) 避免上下文重复使用一个变量,使用final 描述可以强制重新定义一个变量,方便更好
地进行重构。
【推荐】集合初始化时,指定集合初始值大小。
说明: HashMap 使用 HashMap(int initialCapacity) 初始化,
正例: initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader
factor)默认为 0.75, 如果暂时无法确定初始值大小,请设置为 16(即默认值)。
【强制】 SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为
static ,必须加锁,或者使用 DateUtils 工具类。
正例:注意线程安全,使用 DateUtils 。亦推荐如下处理:
private static finalThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@ Override
protected DateFormat initialValue() {
return newSimpleDateFormat("yyyy-MM-dd");
}
};
说明:如果是 JDK 8 的应用,可以使用 Instant 代替 Date , LocalDateTime 代替 Calendar ,
DateTimeFormatter 代替SimpleDateFormat ,官方给出的解释: simple beautiful strong
immutable thread - safe 。
【强制】多线程并行处理定时任务时,Timer 运行多个 TimeTask 时,只要其中之一没有捕获
抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService 则没有这个问题。
【参考】 HashMap 在容量不够进行resize 时由于高并发可能出现死链,导致 CPU 飙升,在
开发过程中可以使用其它数据结构或加锁来规避此风险。
【强制】在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
说明:不要在方法体内定义: Pattern pattern = Pattern .compile( 规则 );
【强制】后台输送给页面的变量必须加 $!{var} ——中间的感叹号。
说明:如果 var = null 或者不存在,那么 ${var} 会直接显示在页面上。
【强制】注意 Math . random() 这个方法返回是double 类型,注意取值的范围 0≤ x <1 (能够取到零值,注意除零异常) ,如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后
取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。
【推荐】任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
【强制】小数类型为 decimal ,禁止使用 float 和 double 。
说明: float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不
正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。
【推荐】单表行数超过 500 万行或者单表容量超过 2 GB ,才推荐进行分库分表。
【推荐】 in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内
【强制】不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
【推荐】不要写一个大而全的数据更新接口。传入为 POJO 类,不管是不是自己的目标更新字段,都进行 update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行 SQL
时,不要更新无改动的字段,一是易出错; 二是效率低 ; 三是增加 binlog 存储。
00