软件开发

当前位置:首页 > 软件开发

阿里Java开发手册(续)

(十一) 其他 

1. 【强制】在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。

说明:不要在方法体内定义:Pattern pattern = Pattern.compile(“规则”); 

2. 【强制】避免用 Apache Beanutils 进行属性的 copy。 

说明:Apache BeanUtils 性能较差,可以使用其他方案比如 Spring BeanUtils, Cglib BeanCopier,注意 均是浅拷贝。

3. 【强制】velocity 调用 POJO 类的属性时,直接使用属性名取值即可,模板引擎会自动按规范 调用 POJO getXxx(),如果是 boolean 基本数据类型变量(boolean 命名不需要加 is 前缀会自动调用 isXxx()方法。

说明:注意如果是 Boolean 包装类对象,优先调用 getXxx()的方法。 

4. 【强制】后台输送给页面的变量必须加$!{var}——中间的感叹号。

说明:如果 var 等于 null 或者不存在,那么${var}会直接显示在页面上。

5. 【强制】注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1能够 取到值,注意除零异常,如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后 取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。

6. 【推荐】不要在视图模板中加入任何复杂的逻辑。

说明:根据 MVC 理论,视图的职责是展示,不要抢模型和控制器的活。

7. 【推荐】任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。

8. 【推荐】及时清理不再使用的代码段或配置信息。

说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。

正例:对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三个斜杠(///) 来说明注释掉代码的理由。如:

public static void 
hello
() { 
 
/// 业务方通知活动暂停 
 
// Business business = new Business(); 
 
// business.active(); 
 System
.
out
.
println
(
"it's finished"
); 
}

二、异常日志

(一) 错误码 

1. 【强制】错误码的制定原则:快速溯源、沟通标准化。

说明: 错误码想得过于完美和复杂,就像康熙字典中的生僻字一样,用词似乎精准,但是字典不容易随身 携带并且简单易懂。

正例:错误码回答的问题是谁的错?错在哪?1)错误码必须能够快速知晓错误来源,可快速判断是谁的问 题。2)错误码必须能够进行清晰地比对(代码中容易 equals)。3)错误码有利于团队快速对错误原因达 到一致认知。

2. 【强制】错误码不体现版本号和错误等级信息。

说明:错误码以不断追加的方式进行兼容。错误等级由日志和错误码本身的释义来决定。

3. 【强制】全部正常,但不得不填充错误码时返回五个零:00000。

4. 【强制】错误码为字符串类型,共 5 位,分成两个部分:错误产生来源+四位数字编号。

说明:错误产生来源分为 A/B/C,A 表示错误来源于用户,比如参数错误,用户安装版本过低,用户支付 超时等问题;B 表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;C 表示错误来源 于第三方服务,比如 CDN 服务出错,消息投递超时等问题;四位数字编号从 0001 到 9999,大类之间的 步长间距预留 100,参考文末附表 3

5. 【强制】编号不与公司业务架构,更不与组织架构挂钩,以先到先得的原则在统一平台上进行, 审批生效,编号即被永久固定。

6. 【强制】错误码使用者避免随意定义新的错误码。

说明:尽可能在原有错误码附表中找到语义相同或者相近的错误码在代码中使用即可。

7. 【强制】错误码不能直接输出给用户作为提示信息使用。

说明:堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip) 是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。 

8. 【推荐】错误码之外的业务独特信息由 error_message 来承载,而不是让错误码本身涵盖过 多具体业务属性。

9. 【推荐】在获取第三方服务错误码时,向上抛出允许本系统转义,由 C 转为 B,并且在错误信 息上带上原有的第三方错误码。

10.【参考】错误码分为一级宏观错误码、二级宏观错误码、三级宏观错误码。

说明:在无法更加具体确定的错误场景中,可以直接使用一级宏观错误码,分别是:A0001(用户端错误)、B0001(系统执行出错)、C0001(调用第三方服务出错)。

正例:调用第三方服务出错是一级,中间件错误是二级,消息服务出错是三级。

11.【参考】错误码的后三位编号与 HTTP 状态码没有任何关系。

12.【参考】错误码有利于不同文化背景的开发者进行交流与代码协作。

说明:英文单词形式的错误码不利于非英语母语国家(如阿拉伯语、希伯来语、俄罗斯语等)之间的开发 者互相协作。

13.【参考】错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆 和分类。

说明:数字是一个整体,每位数字的地位和含义是相同的。

反例:一个五位数字 12345,第 1 位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地 拆开并分辨每位数字的不同含义。

(二) 异常处理 

1. 【强制】Java 类库中定义的可以通过预检查方式规避的 RuntimeException 异常不应该通过 catch 的方式来处理,比如:NullPointerExceptionIndexOutOfBoundsException 等等。 

说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字时,可能存在数字格式错误,不得不 通过 catch NumberFormatException 来实现。

正例:if (obj != null) {...} 

反例:try { obj.method(); } catch (NullPointerException e) {…} 

2. 【强制】异常捕获后不要用来做流程控制,条件控制。

说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。

3. 【强制】catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。 对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。

说明:对大段代码进行 try-catch,使程序无法根据不同的异常做出正确的应激反应,也不利于定位问题, 这是一种不负责任的表现。 

正例:用户注册的场景中,如果用户输入非法字符,或用户名称已存在,或用户输入密码过于简单,在程 序上作出分门别类的判断,并提示给用户。

4. 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请 将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的 内容。

5. 【强制】事务场景中,抛出异常被 catch 后,如果需要回滚,一定要注意手动回滚事务。

6. 【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。

说明:如果 JDK7 及以上,可以使用 try-with-resources 方式。

7. 【强制】不要在 finally 块中使用 return

说明:try 块中的 return 语句执行成功后,并不马上返回,而是继续执行 finally 块中的语句,如果此处存 在 return 语句,则在此直接返回,无情丢弃掉 try 块中的返回点。 

反例:

 
private int 
x 
= 
0
; 
public int 
checkReturn
() { 
 
try 
{ 
 
// x 等于 1,此处不返回 
 
return 
++
x
; 
 
} 
finally 
{ 
 
// 返回的结果是 2 
 
return 
++
x
; 
 
} 
}


相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~