开发规范
开发规范原则
- 规范。保证您的代码规范,保证结构表现行为相互分离。
- 简洁。保证代码的最简化,避免多余的空格、空行,保持代码的语义化。任何时候都要用尽量简单、尽量少的元素解决问题。
- 实用。遵循标准,但是不能以牺牲实用性为代价。
- 忠诚。选择一套规范,然后始终遵循。不管代码由多少人参与,都应该看起来像一个人写的一样
1 Web开发规范
1.1 一般规范
文件/资源命名
- 文件命名总是以字母开头而不是数字
- 以减号(-)是用来分隔文件名,例:1001-scripts.js
- 名称必须全为小写。因为在某些对大小写字母敏感的操作系统中,当文件通过工具压缩混淆后,或者人为修改过后,大小写不同而导致引用文件不同的错误,很难被发现。
- 需要对文件增加前后缀或特定的扩展,使用“.”分隔符来区分,例如:my-file.min.css
不要指定引入资源所带的具体协议
不推荐:<script src="http://cdn.com/foundation.min.js"></script>
推荐:<script type="text/javascript" src="<%=request.getContextPath()%>/js/echarts.js"></script>
不推荐:.example {background: url(http://static.example.com/images/bg.jpg);}
推荐:.general-box{ background:url(../images/general.png);}
文本缩进:一次缩进4个空格
html 代码:
<ul>
<li>Fantastic</li>
<li>Great</li>
<li>
<a href="#">Test</a>
</li>
</ul>
css 代码:
.body {
font-size: 100%;
}
js 代码:
$(document).ready(function(){
$(".menu li").hover(function(){
$(this).addClass("hover");
$(this).children("ul li").attr('class','');
},function(){
$(this).removeClass("hover");
$(this).children("ul li").attr('class','');
}
);
注释
不推荐:
//用户信息展示
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}
推荐:
/** 用户信息展示 */
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}
1.2 HTML规范
- html标签、属性全部小写
- 双标签必须闭合,单标签(自关闭标签)不闭合 如 <hr>
- 属性值使用("")双引号,不要使用('')
- html属性应该按照特定的顺序出现以保证易读性。class->id,name->data-*->src,for,type,href->title,alt->aria-*,role,value。
- 尽量避免<body></body>中编写javascript代码,例如
<table class="simple-table" id="opHistoryTable1">
<tr>
<th width="100">时间</th>
<th width="70">IP状态</th>
<th>访问情况</th>
</tr>
</table>
<script>
$(".nicescroll2").niceScroll({
cursorcolor : "#000",
cursoropacitymax : 0.3,
horizrailenabled : true,
touchbehavior : false,
cursorwidth : "10px",
cursorborder : "0",
cursorborderradius : "8px"
});
</script>
- 尽量避免使用style属性
1.3 CSS规范
层次结构
- 全局global.css:全局样式为全站公用,为页面样式基础,页面中必须包含。
- 结构layout.css:页面结构类型复杂,并且公用类型较多时使用。多用在首页级页面和产品类页面中。
- 私有style.css:独立页面所使用的样式文件,页面中必须包含。
- 模块module.css:产品类页面应用,将可复用类模块进行剥离后,可与其它样式配合使用。
- 主题themes.css:实现换肤功能时应用。
命名规范
- 头:header
- 内容:content/containe
- 尾:footer
- 导航:nav
- 侧栏:sidebar
- 栏目:column
- 页面外围控制整体布局宽度:wrapper
- 左右中:left right center
- 登录条:loginbar
- 标志:logo
- 广告:banner
- 页面主体:main
- 热点:hot
- 新闻:news
- 下载:download
- 子导航:subnav
- 菜单:menu
- 子菜单:submenu
- 搜索:search
- 友情链接:friendlink
- 页脚:footer
- 版权:copyright
- 滚动:scroll
- 内容:content
- 标签页:tab
- 文章列表:list
- 提示信息:msg
- 小技巧:tips
- 栏目标题:title
- 加入:joinus
- 指南:guild
- 服务:service
- 注册:regsiter
- 状态:status
- 投票:vote
- 合作伙伴:partner
其它
- 命名统一采用小写;
- 尽量用英文;
- 不加中杠和下划线;
- 尽量不缩写,除非一看就明白的单词
- 定义颜色时使用颜色的名称或者16进制代码
- 若有子标签样式,最好放在一起,例如:
.model{ margin:0 5px;}
.model li{ width:154px;}
- 省略“0”值后面的单位,例如:margin: 0;
- 不建议所有属性都写在同一行,例如:.model-cont ul li{ width:154px; height:36px; line-height:36px; background:#00a0e9; margin:5px 0 0 10px; font-size:14px; color:#fff; pad...
建议
.box {
display: block;
position: absolute;
left: 30%;
right: 30%;
overflow: hidden;
margin: 1em;
padding: 1em;
background-color: #eee;
border: 3px solid #ddd;
font-family: 'Arial', sans-serif;
font-size: 1.5rem;
text-transform: uppercase;
}
- 最好能够遵循以下属性顺序
结构性属性:
display
position, left, top, right.
overflow, float, clear.
margin, padding
表现性属性:
background, border.
font, text
1.4 JavaScript规范
- 变量和方法名采用首字母小写的驼峰式命名规则
- 声明变量“=”前后最好添加空格,例:var a = 0;
- 常量:必须采用全大写的命名,且单词以_分割
- 类:必须采用骆驼峰的命名且首字母大写,例如:
// 正确的写法
var FooAndToo = function(name) {
this.name = name;
}
- 每句代码后必须加";",例如:
a = b // 赋值
(function(){
//....
})() // 自执行函数
未加分号会被解析成a = b(function(){//...})() //将b()()返回的结果赋值给a
- 在同一个函数内部,局部变量的声明最好置于顶端,因为即使放到中间,js解析器也会提升至顶部
- 空格的使用:
//推荐的写法
if (isOk) {
console.log("ok");
}
//不推荐的写法
if(isOk){
console.log("ok");
}
//推荐的写法
switch(name) {
//不推荐的写法
switch (name) {
//推荐的写法
for (i=0, len=names.length; i < len; i++) {
//不推荐的写法
for(i = 0, len = names.length;i < len;i++) {
//推荐的写法
var cell = function () {
//不推荐的写法
var call = function(name){
- 块内函数必须用局部变量声明
//不推荐的写法
var call = function(name) {
if (name == "hotel") {
function foo() {
console.log("hotel foo");
}
}
foo && foo();
}
// 推荐的写法
var call = function(name) {
var foo;
if (name == "hotel") {
foo = function() {
console.log("hotel foo");
}
}
foo && foo();
}
- 不用使用eval,采取$.parseJSON,主要是因为:有注入风险,尤其是ajax返回数据;不方便debug;效率低,eval是一个执行效率很低的函数
备注:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。若莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码…,那就等着悲剧吧。
- If…else…等不要简写
- 推荐在需要以{}闭合的代码段前增加换行
2 后台开发规范
2.1 应用分层
- 终端显示层:各个端的模板渲染并执行显示层。当前主要是velocity渲染,JS渲染,JSP渲染,移动端展示层等。
- Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
- Service层:相对具体的业务逻辑服务层。
- DAO层:数据访问层,与底层Mysql、Oracle、Hbase、OB进行数据交互。外部接口或第三方平台:包括其它部门RPC开放接口,基础平台,其它公司的HTTP接口。
注意:
(1)DAO层一般与数据进行交互,产生的异常类型有很多,无法用细粒度异常进行try…catch,使用catch(Exception e)方式,并throw newDaoException(e),不需要打印日志。
(2)Service层出现异常时,必须记录日志信息,尽可能带上参数信息,相当于保护案发现场。
(3)Web层不应该继续往上抛异常,因为已经处于顶层,无继续处理异常的方式,特殊情况除外(应该直接跳转到友好错误页面,尽量加上友好的错误提示信息)
(4)调用规范:终端显示层 -- Web层 -- Service层 -- DAO层,Service层和DAO层通过接口实现调用,不要直接调用实现类(若需要静态类,可直接调用静态类)
(5)若有需要进行一些规则的校验,可放在Web层(简单数据校验)和Service层(业务逻辑校验)。
2.2 分层领域模型
- DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
- BO(Business Object):业务对象。可以由Service层输出的封装业务逻辑的对象。
- VO(View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
注意:定义分层领域模型时,不要设定任何属性默认值,也不要采用is开头的变量。
2.3 命名规范
- 所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例: _name / __name / $Object / name_ / name$ / Object$
- 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。反例: DaZhePromotion [打折] / getPingfenByName() [评分] / int 变量 = 3; 正例: ali / alibaba / taobao /cainiao / aliyun / youku / hangzhou 等国际通用的名称,可视为英文。
- 杜绝完全不规范的缩写,避免望文不知义。反例:<某业务代码>AbstractClass“缩写”命名成AbsClass;condition“缩写”命名成 condi,此类随意缩写严重降低了代码的可阅读性。
- 包命名:统一使用小写
- 类命名:首字母大写的驼峰形式(UpperCamelCase),领域模型类的命名按类命名方式,以DO / BO / VO结尾,例如: MarcoPolo / UserDO / XmlService
- 方法名、参数名、成员变量、局部变量:统一使用首字母小写的驼峰形式(lowerCamelCase),例如:localValue / getHttpMessage() / inputUserId。
- 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚。例如: MAX_STOCK_COUNT
- 数组定义如下:String[] args; 勿使用String args[]的方式来定义
- Service/DAO层方法命名:查询的方法用get或query作前缀,如果涉及获取多个对象,可以List作为后缀;统计值的方法以count作为前缀;插入的方法用save(推荐)或insert做前缀;删除的方法用remove(推荐)或delete做前缀;修改的方法用update做前缀。
- 领域模型命名:数据对象:xxxDO,xxx即为数据表名,如果表名带下划线,xxx去掉下划线;业务对象:xxxBO,xxx为业务领域相关的名称;展示对象:xxxVO,xxx一般为网页名称。
2.4 常量定义
- 不允许出现任何未经定义的常量直接出现在代码中,例如:String key="Id#taobao_"+tradeId;
- long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1 混淆,造成误解。
- 不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类:CacheConsts下;系统配置相关的常量放在类:ConfigConsts下。
- 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
1)跨应用共享常量:通常是架包中的const目录下。
2)应用内共享常量:放置在一方库的modules中的const目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位工程师在两个类中分别定义了表示
“是”的变量:
类A中:public static final String YES ="yes";
类B中:public static final String YES = "y";
A.YES.equals(B.YES),预期是true,但实际返回为false,导致产生线上问题。
3)子工程内部共享常量:即在当前子工程的const目录下。
4)包内共享常量:即在当前包下单独的const目录下。
5)类内共享常量:直接在类内部private static final定义。
2.5 OOP规范
- 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
- 不要使用过时的类或方法。
- 循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。
- 类成员与方法访问控制从严:
1) 如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
2) 工具类不要有public或default构造方法。
3) 类非static成员变量并且与子类共享,必须是protected。
4) 类非static成员变量并且仅在本类使用,必须是private。
5) 类static成员变量如果仅在本类使用,必须是private。
6) 若是static成员变量,必须考虑是否为final。
7) 类成员方法只供类内部调用,必须是private。
8) 类成员方法只对继承类公开,那么限制为protected。
注意:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
- 涉及表的增删改均需要异常处理
- java文件约定
1)建议单个类的长度包括注释行不超过1500行。 尽量避免使用大类和长方法。
2)每行代码字数不超过150字
3)类中的方法最好不要超过3个翻页,方便阅读
4)一个方法构造的参数个数不超过5个。
- 异常处理
1)当捕捉到异常时,必须处理catch代码区,打印错误信息,统一用log4j统一日志输出
2)应该尽可能的精确捕捉异常。原因:精确的捕捉异常能够帮助你了解代码和确切知道你要做什么。
3)try最多被嵌套3层。
- 文件字符集统一使用UTF-8标准(包括JSP/HTML/CSS/.PROPERTIES等)
- 尽量使用StringBuffer,而不用String来累加字符串,因为String一旦初始化后是不能变的,所以在每执行一次+号时,相当于创建一个StringBuffer对象,然后append,最后返回一个String,所以在这个过程中无疑会增加系统的负担。
- 能用基本类型如Int,Long,就不用Integer,Long对象
- 尽量少用静态对象变量,静态对象过多造成大量占用java虚拟机的内存,影响系统的数据处理过程,甚者造成内存溢出,如果真的需要很多变量,可以采用xml文件配置方式
- 判空方式:
字符串判空:
String a = "";
if (null != a && !a.equals("")) {
...
}
数组判空:
String[] a = null;
if(null != a && a.length > 0){
...
}
List对象判空
List list = new ArrayList();;
if (null != list && list.size() > 0) {
...
}
- 变量一定要初始化
2.6 注释规范
- 注释必须使用javadoc规范,使用/**内容*/格式,不要使用//xxx方式。
说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
- 类最好注释类的作用和创建者信息。
- 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
- 所有的枚举类型字段必须要有注释,说明每个数据项的用途。
- 与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词、关键字,保持英文原文即可。
- 方法的注释如果有接口,一般在接口对于的方法法进行注释,没有则在方法上进行注释
2.7 日志规范
- 谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志(关键的业务逻辑点)
- 必须适用LOG作为日志处理,在重要环节要有入口和出口日志,对catch到的内容必须log报异常。
-
- 常见错误
(1)入参和查询结果未判空,导致报空指针异常
错误示例:
for(int i=0;i<list.size();i++){
……
}
正确示例:
if(null != list && list.size() > 0){
for(int i=0;i< list.size();i++){
……
}
}
(2)代码中包含SysTem.out.println
(3)用“==”比较两个字符串内容相等
String a = new String("a");
String a2 = "a";
错误:a == a2
正确:a.equals(a2)
(4)在foreach循环中修改list结构
for(Person p : list) {
if("王五".equals(p.getName())) {
list.remove(p); // 不能在此时删除对象。</span>
}
}
(5)直接使用数据进行对比,让人不知其意(即魔鬼数字问题),例如:
错误:"1".equals(logType) || "7".equals(logType),
正确:(PickConst.LOG_TYPE_OPERATOR.equals(logType) || PickConst.LOG_TYPE_TRAFFIC.equals(logType))
(6)数组越界异常:
String[] cIds;
错误:System.out.println(cIds[0] .toCharArray());
正确:if(null != cIds && cIds.length > 0) {
System.out.println(cIds[0] .toCharArray());
}
(7)使用文件、IO流、数据库连接未将其关闭,且应该在try...catch...finally的finally内执行
错误示例:
public voidwriteProduct1(ProductServiceStruct product) {
try{
FileWriter fileWriter = new FileWriter("");
fileWriter.append(product.toString());
// 如果append()抛出异常,close()方法就不会执行,造成IO流长时间无法释放
fileWriter.close();
} catch(IOException e) {
...
}
}
正确示例:
public voidwriteProduct2(ProductServiceStruct product) {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("");
fileWriter.append(product.toString());
} catch(IOException e) {
...
//记录日志
} finally {
// 不管前面是否发生异常,finally中的代码一定会执行
if(fileWriter != null) {
try {
fileWriter.close();
} catch(IOException e) {
...
//记录日志
}
}
}
}
(8)循环体内使用try...catch,应放在循环体外
(9)使用错误的三元操作符,例:foo.toString()!==""?true:false;
(10)对数据库进行更删改时,没有使用事务进行控制(一般是框架进行事务控制)
3. 具体规范要求
开发规范开发规范原则
1 Web开发规范1.1 一般规范文件/资源命名
不要指定引入资源所带的具体协议 不推荐:<script src="http://cdn.com/foundation.min.js"></script> 推荐:<script type="text/javascript" src="<%=request.getContextPath()%>/js/echarts.js"></script> 不推荐:.example {background: url(http://static.example.com/images/bg.jpg);} 推荐:.general-box{ background:url(../images/general.png);} 文本缩进:一次缩进4个空格 html 代码: <ul> <li>Fantastic</li> <li>Great</li> <li> <a href="#">Test</a> </li> </ul> css 代码: .body { font-size: 100%; } js 代码: $(document).ready(function(){ $(".menu li").hover(function(){ $(this).addClass("hover"); $(this).children("ul li").attr('class',''); },function(){ $(this).removeClass("hover"); $(this).children("ul li").attr('class',''); } ); 注释 不推荐: //用户信息展示 function showOperaterMessage(data){ var url = getUrlRoot() + '/appView.do?method=appInfo' + data; window.open(url); } 推荐: /** 用户信息展示 */ function showOperaterMessage(data){ var url = getUrlRoot() + '/appView.do?method=appInfo' + data; window.open(url); } 1.2 HTML规范
<table class="simple-table" id="opHistoryTable1"> <tr> <th width="100">时间</th> <th width="70">IP状态</th> <th>访问情况</th> </tr> </table> <script> $(".nicescroll2").niceScroll({ cursorcolor : "#000", cursoropacitymax : 0.3, horizrailenabled : true, touchbehavior : false, cursorwidth : "10px", cursorborder : "0", cursorborderradius : "8px" }); </script>
1.3 CSS规范层次结构
命名规范
其它
.model{ margin:0 5px;} .model li{ width:154px;}
建议 .box { display: block; position: absolute; left: 30%; right: 30%; overflow: hidden; margin: 1em; padding: 1em; background-color: #eee; border: 3px solid #ddd; font-family: 'Arial', sans-serif; font-size: 1.5rem; text-transform: uppercase; }
结构性属性: display position, left, top, right. overflow, float, clear. margin, padding 表现性属性: background, border. font, text 1.4 JavaScript规范
// 正确的写法 var FooAndToo = function(name) { this.name = name; }
a = b // 赋值 (function(){ //.... })() // 自执行函数 未加分号会被解析成a = b(function(){//...})() //将b()()返回的结果赋值给a
//推荐的写法 if (isOk) { console.log("ok"); } //不推荐的写法 if(isOk){ console.log("ok"); } //推荐的写法 switch(name) { //不推荐的写法 switch (name) { //推荐的写法 for (i=0, len=names.length; i < len; i++) { //不推荐的写法 for(i = 0, len = names.length;i < len;i++) { //推荐的写法 var cell = function () { //不推荐的写法 var call = function(name){
//不推荐的写法 var call = function(name) { if (name == "hotel") { function foo() { console.log("hotel foo"); } } foo && foo(); } // 推荐的写法 var call = function(name) { var foo; if (name == "hotel") { foo = function() { console.log("hotel foo"); } } foo && foo(); }
备注:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。若莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码…,那就等着悲剧吧。
2 后台开发规范2.1 应用分层
注意: (1)DAO层一般与数据进行交互,产生的异常类型有很多,无法用细粒度异常进行try…catch,使用catch(Exception e)方式,并throw newDaoException(e),不需要打印日志。 (2)Service层出现异常时,必须记录日志信息,尽可能带上参数信息,相当于保护案发现场。 (3)Web层不应该继续往上抛异常,因为已经处于顶层,无继续处理异常的方式,特殊情况除外(应该直接跳转到友好错误页面,尽量加上友好的错误提示信息) (4)调用规范:终端显示层 -- Web层 -- Service层 -- DAO层,Service层和DAO层通过接口实现调用,不要直接调用实现类(若需要静态类,可直接调用静态类) (5)若有需要进行一些规则的校验,可放在Web层(简单数据校验)和Service层(业务逻辑校验)。 2.2 分层领域模型
注意:定义分层领域模型时,不要设定任何属性默认值,也不要采用is开头的变量。 2.3 命名规范
2.4 常量定义
1)跨应用共享常量:通常是架包中的const目录下。 2)应用内共享常量:放置在一方库的modules中的const目录下。 反例:易懂变量也要统一定义成应用内共享常量,两位工程师在两个类中分别定义了表示 “是”的变量: 类A中:public static final String YES ="yes"; 类B中:public static final String YES = "y"; A.YES.equals(B.YES),预期是true,但实际返回为false,导致产生线上问题。 3)子工程内部共享常量:即在当前子工程的const目录下。 4)包内共享常量:即在当前包下单独的const目录下。 5)类内共享常量:直接在类内部private static final定义。 2.5 OOP规范
1) 如果不允许外部直接通过new来创建对象,那么构造方法必须是private。 2) 工具类不要有public或default构造方法。 3) 类非static成员变量并且与子类共享,必须是protected。 4) 类非static成员变量并且仅在本类使用,必须是private。 5) 类static成员变量如果仅在本类使用,必须是private。 6) 若是static成员变量,必须考虑是否为final。 7) 类成员方法只供类内部调用,必须是private。 8) 类成员方法只对继承类公开,那么限制为protected。 注意:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
1)建议单个类的长度包括注释行不超过1500行。 尽量避免使用大类和长方法。 2)每行代码字数不超过150字 3)类中的方法最好不要超过3个翻页,方便阅读 4)一个方法构造的参数个数不超过5个。
1)当捕捉到异常时,必须处理catch代码区,打印错误信息,统一用log4j统一日志输出 2)应该尽可能的精确捕捉异常。原因:精确的捕捉异常能够帮助你了解代码和确切知道你要做什么。 3)try最多被嵌套3层。
字符串判空: String a = ""; if (null != a && !a.equals("")) { ... } 数组判空: String[] a = null; if(null != a && a.length > 0){ ... } List对象判空 List list = new ArrayList();; if (null != list && list.size() > 0) { ... }
2.6 注释规范
说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
2.7 日志规范
(1)入参和查询结果未判空,导致报空指针异常 错误示例: for(int i=0;i<list.size();i++){ …… } 正确示例: if(null != list && list.size() > 0){ for(int i=0;i< list.size();i++){ …… } } (2)代码中包含SysTem.out.println (3)用“==”比较两个字符串内容相等 String a = new String("a"); String a2 = "a"; 错误:a == a2 正确:a.equals(a2) (4)在foreach循环中修改list结构 for(Person p : list) { if("王五".equals(p.getName())) { list.remove(p); // 不能在此时删除对象。</span> } } (5)直接使用数据进行对比,让人不知其意(即魔鬼数字问题),例如: 错误:"1".equals(logType) || "7".equals(logType), 正确:(PickConst.LOG_TYPE_OPERATOR.equals(logType) || PickConst.LOG_TYPE_TRAFFIC.equals(logType)) (6)数组越界异常: String[] cIds; 错误:System.out.println(cIds[0] .toCharArray()); 正确:if(null != cIds && cIds.length > 0) { System.out.println(cIds[0] .toCharArray()); } (7)使用文件、IO流、数据库连接未将其关闭,且应该在try...catch...finally的finally内执行 错误示例: public voidwriteProduct1(ProductServiceStruct product) { try{ FileWriter fileWriter = new FileWriter(""); fileWriter.append(product.toString()); // 如果append()抛出异常,close()方法就不会执行,造成IO流长时间无法释放 fileWriter.close(); } catch(IOException e) { ... } } 正确示例: public voidwriteProduct2(ProductServiceStruct product) { FileWriter fileWriter = null; try { fileWriter = new FileWriter(""); fileWriter.append(product.toString()); } catch(IOException e) { ... //记录日志 } finally { // 不管前面是否发生异常,finally中的代码一定会执行 if(fileWriter != null) { try { fileWriter.close(); } catch(IOException e) { ... //记录日志 } } } } (8)循环体内使用try...catch,应放在循环体外 (9)使用错误的三元操作符,例:foo.toString()!==""?true:false; (10)对数据库进行更删改时,没有使用事务进行控制(一般是框架进行事务控制) 3. 具体规范要求
| |||||||||||||||||||||||||||||||||||||||||||||