目录
.概述
1.1背景
编码规范对于程序员而言尤为重要,有以下几个原因:
- 一个软件的生命周期中,80%的花费在于维护
- 几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护
- 规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的设计和代码
- 良好的编码规范可以有效避免一些低级错误
1.2目的
- 统一规范,方便阅读、维护,提高代码质量
- 统一格式,使代码度量更加精确,为公司软件过程体系优化打好基础。
1.3适用范围
全公司所有JAVA项目及程序
1.4名词解释
- Pascal命名法:每个单词的首字母都大写。如:BackColor
- Camel 命名法(驼峰命名法):首字母小写,后面每个单词的首字母都大写。如:backColor
- Underline 命名法(下划线命名法):单词中间用下划线分割。如:string user_name;
- 中划线命名法:所有字母均小写,单词中间用中划线"-"分割。如:user-list.jsp
- 匈牙利命名法:变量名=属性+类型+对象描述。如:btnUserName,只允许控件命名使用。
1.5文档说明
- 是在业界通用规范基础上结合公司现有规范制定的
- 符合主流IED工具,符合开发人员的大多数习惯
- 尽量减少规范的描述篇幅,使之易阅读
2.文件规范
2.1文件编码
项目中如下文件均采用UTF-8编码格式:
.java .jsp .js .html .htm .shtml .vm .ftl .xml .txt .json .css |
2.2文件命名
文件类型 | 命名方式 | 示例 |
.java | Pascal命名法 | CookieUtil.java |
.jsp .js .html .htm | 中划线命名法 | view-bundle.ftl |
2.3配置文件的选择
- .properties配置文件:可读性差、不容易扩展,中文还需要转码,不推荐使用。若配置内容特别少,只有单一格式的英文字母,则可以使用。
- .xml配置文件:结构化好、扩展性强、可自我校验,推荐使用。
3.排版风格
3.1总原则
- 采用eclipse作为开发工具,编码风格总体和eclipse编码风格一致。
- 写代码时,不必特意设定空格、对齐等;写完一个方法或一个类后,用eclipse的格式化工具完成格式化即可,快捷键:CTRL+Shift+F
- 注意:Eclipse格式化工具默认会进行空格、缩进排版,会自动在两个函数间加入空行,但不会自动修改函数体内的空行——即:函数体内语句间如果需要空行,则要手工加入。
3.2列宽/换行
- 每行代码的字符数不超过120 个,eclipse的格式化工具默认为80个字符,更改方法如下:
Window->Preferences>Java>Code Style>Formatter>右侧窗口Edit按钮>弹出窗口中Line Wrapping选项卡->Maximum line width
2. 在任何情况下, 超长的语句应该在一个逗号后或一个操作符前折行。
例1,逗号后换行:
public static JSONObject wrap(Object data, boolean successs, long results, |
例2,操作符换前换行:
String finalMethodName = "init" + firstChar |
例3,属性操作符前换行:
char firstChar = Character.toTitleCase(invokeMethod |
3. 一条语句折行后, 应该比原来的语句再缩进4个空格,以便于阅读。
3.3声明
每行只能声明一个变量,如:
// indentation level
|
禁止:
int level, size; |
3.4缩进
-
每个缩进单位为4个英文空格,不要在代码中使用Tab字符,可以在开发工具中将tab键设置为4个字符,eclipse设置缩进方法如下:
WindowPreferencesjavacodestyleFormatter,然后点击edit按钮,在Indentation页签中的General Settings选项集里,将Tab policy由Tabs only改为Spaces only,并保持Indetation size和tab size为4, 最后在最上方的Profile name里任意输入字符,保存当前页设置即可
-
按层级缩进,缩进层级不能超过5层,否则需要拆分函数
public void methodName(int age) {
int avgAge = 10;
if (age < avgAge) {
for (int i = 0; i < 5; i++) {
// some sentences
}// end for
}// end if
}3.5空行
使用一个空行情况:
- 两个方法之间
- 方法内的局部变量和方法的第一条语句之间
- 块注释或单行注释之前
- 一个方法内的两个逻辑段之间,用以提高可读性
两个空行使用情况:
- 一个源文件的两个片段(section)之间
- 类声明和接口声明之间
3.6空格
需要增加空格的地方有:
情形 | 示例 |
在大多数运算符之前和之后 | if (a + b > c) |
"(" 的前面 | 例如:if ((a>b) && (c>d)) 不要写成 if((a>b)&&(c>d)) |
|, &, ||, && 前后 | if (a>b && c>d) |
"=" 前后 | a = 100; |
三元操作符 ? : 的前后 | maxValue = a>b ? a : b; |
函数调用的各个参数之间 | getData(param1, param2, param3); |
比较符前后 | a > b //不强制 |
case 的后面 | case "none" |
语句表达式之间 | for (expr1; expr2; expr3) |
3.7对齐
- 当方法参数过多时当在每个参数后(逗号后)换行并对齐。
- 当控制或循环中的条件比较长时当换行(操作符前)、对齐并注释各条件。
- 变量定义最好通过添加空格形成对齐,同一类型的变量应放在一起。
3.8小括号
1. 当不清楚是否应该加小括号时请添加小括号,否则很难看明白其含义。
推荐:
if (((a - b) << 2) > ((c - d) >> 4)) { |
不推荐:
if (a - b << 2 > c - d >> 4) { |
2. 尽量不要在返回语句中使用()。
3.9花括号
{} 中的语句应该单独作为一行,左括号"{"当紧跟其语句后(即:在它后面换行),右括号"}"永远单独作为一行且与其匹配行对齐,并尽量在其后说明其匹配的功能模块。如:
public String getFirstNode(List<String> nodeList) { |
3.10代码长度
- 单个方法的有效代码长度当尽量控制在100行以内(不包括注释行)
- 单个类的长度包括注释行不超过1500行。
4.命名规范
4.1命名总则
- 使用可以准确说明变量/字段/类/接口/包等的完整的英文描述符。例如,采用类似firstName,listAllUsers这样的名字,严禁使用汉语拼音及不相关单词命名。
- 采用该领域的术语。如果用户称他们的"客户" (clients) 为"顾客" (customers),那么就采用术语 Customer 来命名这个类,而不用 Client。
- 尽量少用缩写,但如果一定要使用,当使用公共缩写和习惯缩写等,如实现(implement)可缩写成impl,经理(manager)可缩写成mgr等,,严禁滥用缩写。
- 避免使用长名字(最好不超过 25 个字母)。
- 避免使用相似或者仅在大小写上有区别的名字。
- 避免使用数字,但可用2代替to,用4代替for,如:map2map。
- 命名时应使用复数来表示它们代表多值,如:orderItems。
4.2命名空间
- Java文件名所有单词首字母大写。
- 包名一般以项目或模块名命名,少用缩写和长名,一律小写。
- 不要用java, javax作为自定义包的前缀
- 基本包:com.alibaba,所有包、文件都从属于此包。不得将类直接定义在基本包下。
- 每个产品/项目都有一个独立命名空间,如:com.alibaba.xxx下xxx代表某个产品或产品缩写,全局唯一;禁止将类文件直接放在com.alibaba.下。
4.3类与接口
类的名字必须由大写字母开头而其他字母都小写的单词组成,对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母,一般使用名词命名。
public abstract class AbstractWebService { |
接口的第一个字符用"I"开头,Service结尾,实现类的命名统一以"ServiceImpl"结尾。
public interface IUserInfoService{
|
4.4方法
- 方法命名多为动词结构
- 采用有符合问题域意义的单词或单词组合。第一个单词常用一个动词,采用小写,后续的每个单词采用首字母大写,其余小写(特殊字除外如URL),没有特别理由不用下划线作为分隔符
- 在Java中对属性方法命名遵循JavaBean的标准:
getter方法: get+属性名, 对boolean型采用is+属性名,有些特定的属性名用has, can代替is可能更好
setter方法: set+属性名 - 构造方法的命名与类名一致
- 取值使用get前缀,设值使用set前缀,判断类使用is(has)前缀,查询类使用query或find前缀(不建议get),修改类使用modify前缀(不建议update),删除类使用delete前缀等等。例:
getName() |
6. 获取单条记录的:findByXXX()
7. 获取List集合的:listByXXX()
8. 分页查询的:pageXXX()
4.5参数
使用有意义的参数命名,如果可能的话,使用和要赋值的字段一样的名字,并用this区分:
public void setSize(int size) { |
方法参数建议顺序:(被操作者,操作内容,操作标志,其他……) 例:
/** |
4.6属性
以下规则概述属性的命名指南:
- javabean属性命名尽量使用常规的驼峰式命名规则
- 属性名第一个单词尽量避免使用一个字母:如eBook, eMail。
- boolean属性名避免使用 "is" 开头的名称,因为javabean规范的boolean取值操作是isXXX
4.7常量
- 采用完整的英文大写单词,在词与词之间用下划线连接,如:DEFAULT_VALUE。
- 命名尽量简短,不要超过16个字符
- 同一组的常量可以用常量类封装在一起,便于引用和维护
4.8变量
- 变量的命名包括实例变量,静态变量,函数参数的命名。
- 变量的名字必须小写字母开头,后面的单词用大写字母开头,其余小写(特殊单词除外,如URL)
- 对不易清楚识别出该变量类型的变量应使用类型缩写作其前缀,如字符串使用strXXX,boolean使用isXXX,hasXXX等等。
- 命名尽量简短,不要超过16个字符
- 除了生命周期很短的临时变量外,避免采用单字符作为变量名,实例变量的命名不要用单字符。常用的单字符变量如整型用 i、j、 k、 m、 n字符型用c、d、 e,坐标用x、y、z。
- 不要用a、b、c、i、j、n等没有意义的变量命名;
- 不要怕麻烦,要使用带有意义的单词命名,如:userListSize、rowLength等来命名。
4.9集合
-
用名词加集合名称的方式来命名,第一个单词首字母小写,如:
List<User> userList = new ArrayList<User>();
Map<String, User> userMap = new HashMap<String, User>(); - 禁止使用单个字母如l,m来命名。
-
数组应该总是用下面的方式来命名:
4.10异常
- 异常类名由表示该异常类型的单词和Exception组成,如ActionException。
- 异常实例一般使用e、ex等,在多个异常时使用该异常名或简写加E,Ex等组成,如:SQLEx
4.11控件
应采用完整的英文描述符命名组件,遵循匈牙利命名法则。如:btnOK,lblName。
4.12关键字
不要使用语言本身已经占用的关键字或保留字命名。
abstract default if private this |
4.13命名示例
操作项 | 命名约定 | 示例 |
参数 | 使用传递值/对象的完整的英文描符。 | userID |
字段/属性 | 字段采用完整的英文描述,首字母小写,任何中间单词的首字母大写。 | firstName |
布尔型方法 | 用is或has做前缀 | isEnough(), hasMoney() |
类 | 采用完整的英文描述符,所有单词首字母大写 | Customer, CustomerCounterTest |
源文件 | 命名同类的定义 | Customer.java |
部件/组件 | 使用完整的英文描述来说明组件的用途,将组件类型使用匈牙利命名法则作其前缀。 | btnOK, cboTypeList |
构造函数 | 默认的构造函数同类名 | Customer() |
异常类名 | 由表示该异常类型等的单词和Exception组成 | SQLException, ServiceException |
异常实例名 | 通常采用字母 e 、ex表示异常。 | e, ex, SQLEx |
常量 | 全部采用大写字母,单词之间用下划线分隔。 | DEFAULT_NAME |
获取成员函数 | 被访问字段名的前面加上前缀 get。 | getUserName() |
接口/实现类 | 使用I前缀/接口实现类命名同接口去掉I的部分,并以Impl做后缀。 | IUserService/UserServiceImpl |
局部变量 | 采用完整的英文描述符,第一个字母小写 | totalMoney |
循环计数器 | 通常采用字母 i,j,k | i, j, k |
包 | 采用完整的英文描述符,所有单词都小写,所有包属于com.alibaba | com.alibaba.gcp.buyer, |
方法 | 采用完整的英文描述说明方法功能 第一个单词尽可能采用一个生动的动词,除第一个单词外,每个单词第一个字母大写。 | openFile() |
5.语句规范
5.1语句总则
- 统一使用Eclipse格式化工具进行格式化,默认快捷键:Ctrl+Shift+F
- 尽量避免强制类型转换。如果不得不做类型转换,尽量用显式方式。
- If else 中的业务代码行数太长,否则就要考虑用函数封装
- 避免在表达式中用赋值语句
- 避免对浮点类型做等于或不等于判断
- 杜绝魔法数字, for循环的最大数等也要用变量代替,以便知道是什么含义
- 对象比较运算,常量放在前面,比如"aaa".equals(str)
- Boolean的"假"判断格式:if(false==isMax) 而不用if(!isMax),因为非符号"!"不清晰
- 如果一段带有业务逻辑的代码超过两次用到,就将其封装成一个方法
- 单个循环也要用{}
- 每个变量仅有一个唯一的用途
- 单个函数执行单个功能并与其命名相符
- 消除所有编译器警告
- 常数变量声明为final
- 每个if-else if-else语句都有最后一个else以确保处理了全集
-
对于流操作代码的异常捕获有finally操作以关闭流对象,比如:
/**
* desktop的Ajax删除处理
* @return null
*/
public String ajaxDelete() {
PrintWriter out = null;
try {
out = response.getWriter();
deleteModel();
out.write("{success:true}");
} catch (Exception e) {
if (out != null) {
out.write("{success:false}");
}
} finally {
if (out != null) {
out.close();
}
}
return null;
} - 对同步对象的遍历访问必须进行代码同步处理
- 在对Map对象使用迭代遍历过程中保证没有做增减元素操作
- If else判断语句避免头重脚轻,比如if的代码段过大,else的代码很短,这时候要调整结构
- 每一行最多包含一条语句。
5.2循环语句
- 务必检查,杜绝死循环
- 即使循环体只有一条语句,也要用花括号括起
-
尽量不用空语句,特殊情况用到空语句,写好注释,告诉读者这不是bug
for (initialization; condition; update){
//已经在条件中执行
}while (condition){
//暂时什么也不做,
}
注:这样做是为了告诉阅读者,这是正常程序而不是遗漏造成的bug。 - 循环中禁止使用访问数据库的操作,循环内部如果需与数据库交互,而应提前一次性读取出。
5.3Switch-case
- 语句switch中的每个case各占一行。
-
所有的非空 case 语句必须用 break; 语句结束。例:
switch (score) {
case 1:
str = "good";
break;
case 2:
str = "bad";
break;
default:
str = "nothing";
break;
} - 语句switch中的case按字母顺序排列。
- 为所有switch语句提供default分支。
6.注释规范
6.1注释总则
- 如果你的程序不值得注释,那么它很可能也不值得运行。
- 避免使用装饰性内容,保持注释的简洁。
- 注释信息不仅要包括代码的功能,还应给出原因,不要为注释而注释。
- 除变量定义等较短语句的注释可用行尾注释外,其他注释当避免使用行尾注释。
- 注释类型:javadoc注释,失效代码注释(eclipse下ctrl+shift+/),代码细节注释 //。
- 对类、方法、变量等的注释需要符合JavaDoc规范,对每个类、方法都应详细说明其功能、条件、参数等,并使用良好的HTML标记格式化注释,以使生成的JavaDoc易阅读和理解。
- 如果注释太复杂说明程序需要修改调整,使设计更加合理。
- getter、setter方法不用注释
- 注释不能嵌套
- 生成开发文档的需要用中文编写
- 如果需要注释的内容太多,需附加文档进行说明, 注释时加上"参见《****》"
- 距离较远的}必须注释
- 复杂的分支流程必须注释
- 代码质量不高但能正常运行,或者还没有实现的代码用//TODO:声明
- 存在错误隐患的代码用//FIXME:声明
6.2文档注释
Javadoc注释可以产生代码的文档。为了可读性,可以有缩进和格式控制。文档注释常采用一些标签进行文档的特定用途描述,用于帮助Javadoc产生文档,常用的有:
标签 | 应用对象 | 目的 |
@author name | 类/接口 | 描述代码的作者,每个作者对应一个这样的标签 |
@deprecated | 类 | 说明该段API已经被废除 |
@exception name description | 成员方法 | 描述方法抛出的异常 |
@param name description | 成员方法 | 描述成员方法中的参数用途和意义,一个参数对应一个这样的标签 |
@return description | 成员方法 | 描述成员方法的返回值的意义 |
@since | 类/接口 | 描述该段API开始的时间 |
@see ClassName | 类/接口 | 用于引用特定的类描述,一般ClassName用包括包名的全名 |
@see ClassName#memberfunction | 类/接口 | 用于引用特定的类的成员方法的描述,一般ClassName用包括包名的全名 |
@version text | 类/接口 | 版本 |
@inheritDoc | 类/接口 | 继承的文档 |
6.3屏蔽代码
对于临时废弃或为了调试程序而临时屏蔽的代码段,可以注释掉。如:
/** |
6.4类注释
在类、接口定义之前当对其进行注释,一般比较详细,其内容至少要包含:功能说明、@author作者、@version版本, @date创建日期、 (see参照,)since开始版本等几个方面。
为了使形成的文档可读性好,注释中经常带有缩进和格式控制。类描述放在类的类定义的紧前面,不能有任何的空行。
以jdk的Number类为例:
/** |
6.5函数注释
依据标准JavaDoc规范对方法进行注释,以明确该方法功能、作用、各参数含义以及返回值等。复杂的算法用/**/在方法内注解出。
注释可以很详细,为了可读性强也可包含格式控制,方法注释一般包括:
- 方法的主要说明,描述方法完成什么样的功能
- @param c elements to be inserted into this list.(参数说明)
- @return <tt>true</tt> if this list changed as a result of the call.(返回值说明)
- @throws NullPointerException if the specified Collection is null.(异常说明)
- @see如果重载方法必须参考父类的方法
- Eclipse下采用Alt+Shift+J生成Javadoc
/** e.printStackTrace(); |
6.6代码注释
例:
//用户名 |
算法设置
算法描述指在实现级别的描述注释,如在方法内的注释,这样使得程序更加易懂,方便程序算法的修改和BUG的修复。一般采用块/行注释,对于简短的描述采用行注释,不要用文档注释。注释的主要内容包括:
- 某些局部变量的意义和用途
- 复杂的控制结构的注释,如循环,分枝,条件表达式。说明控制所要达到的目标
- 复杂的代码段的描述,说明代码完成的功能,以及为什么这样做。
- 使用@ inheritDoc开始
块注释: /* */
可以用多行,一般用来对程序块、算法实现、类的实现进行说明。为了可读性,可以有缩进和格式控制。一般在行注释不能满足注释需要的时候采用。一般用来作为文件头、复杂算法的说明,方法体内的复杂过程说明等
6.7变量注释
1. 成员变量、类静态变量采用文档注释,对成员变量的注释通常包括:
- 变量的意义
- 变量的合法值域
/** XXXXXX */ |
2. 局部变量,如算法相关的变量采用块或行注释
String username = "xyz"; //用户姓名 |
3. 参数变量注释一般用文档注释,并且用@param来说明为参数,一般包括:
-
- 参数的用途
- 对参数值范围的要求
6.8修改别人的代码
增、删、改
原则上尽量不要修改别人的代码,而是提出需求,由相应的代码责任人负责修改。
如果由于客观条件导致必须修改别人的代码,则尽量征得责任人的同意,同时在修改的地方添加修改注释,格式如下:
-
用"+"表示增加代码
//yangym20120601 +2
int i = getCount();
listCount += i; -
用"-"表示删除代码
/** yangym20120601 -
int i = getCount();
listCount += i;
*/ -
用"*"表示修改代码
//listCount = i;
listCount += i; // yangym20120601 *
添加方法
用标准javadoc对方法进行注释,并注明作者和日期
添加字段
需要添加作者信息注释。如:
String userName = null; //yangym20120601 |
6.9单行注释
//一次只能注释一行,一般用来简短的描述某一个局部变量,程序块的作用。
6.10其他注释
- 应对重要的变量加以注释,以说明其含义等。
- 应对不易理解的分支条件表达式加注释。不易理解的循环,应说明出口条件。过长的方法实现,应将其语句按实现的功能分段加以概括性说明。
- 对于异常处理当注明正常情况及异常情况或者条件,并说明当异常发生时程序当如何处理。
7.编码格式
7.1基本原则
- 一个程序文件最好不要超过1000行
- 尽可能缩小对象的作用域,这样对象的可见范围和生存期也都会尽可能地小
- 一个方法所完成的功能要单一,不同的功能封装为不同的方法.
- 尽可能的处理异常或转换异常,不要一味的包装异常
- 如果对象在某个特定范围内必须被清理(而不是作为垃圾被回收),请使用带有finally子句的try块,在finally子句中进行清理。
- 对成员变量的访问最好通过getter/setter方法,这样能够保证访问的合法性,以及代码调整
- 优先选择接口而不是抽象类或具体类。如果某些东西将成为基类,应当优先把它们设计成接口;只有在必须放进方法定义或成员变量时,才把它修改为具体或抽象类。
- 在处理可变String的时候要必须使用StringBuffer类,可变范围在5次以内可以使用String
- 使用java标准库提供的容器。优先选择ArrayList来处理顺序结构,选择HashSet来处理集合,选择HashMap来处理关联数组,选择linkedList来处理堆栈和队列。当使用前三个的时候,应该把他们向上转型为List、Set和Map,这样就可以在必要的时候以其它方式实现
- 如果数组的长度将来可能突破现有定义,就用ArryList。
- 尽量使用"private"、"protected"关键字,这样对改动影响最小,必要时再定义为public。
- 采用类而不是对象引用静态变量和方法
- 使用Boolean必须采用Boolean.TRUE/Boolean.FALSE进行构造
- Boolean.valueof(true|false|y|n|Y|N)的形式进行构造
-
禁止后台业务层代码使用如下代码,要输出日志,同时进行异常包装抛出。
try{
//do something
}catch(Exception e){
e.printStackTrace();
}7.2类编码格式
import顺序
- import包按一下顺序:
- jdk标准包
- java扩展包(例如servlet,javamail等)
- 使用的外部库的包(例如xml parser)
- 使用的项目的公共包
- 使用的模块的其他包
2. 每一类import后面加一个换行。例如:
import java.io.*; |
3. 类的结构组织,一般按照如下的顺序:
- 常量声明
- 静态变量声明
- 成员变量声明
- 构造函数部分
- Finalize部分
- 成员方法部分
- 静态方法部分
这种顺序是推荐的,在实际开发中可以按照一定的尺度修改,原则是程序更易读。如对方法的排序按照重要性,或按照字母顺序排列或按照方法之间的关系排列。
4. 每个方法(包括构造与finalize)都是一个段。多个变量声明按照逻辑共同组成一个段,段与段之间以空行分隔。
5. 类声明时,要指出其访问控制,一般为没有修饰符,public,和private。
6. 编写通用性的类时,请遵守标准形式。包括定义equals()、hasCode()、toString()、Clone(实现Cloneable接口),并实现Comparable和Serialiable接口
7. 对于设计期间不需要继承的类,尽量使用final
7.3变量
- 对成员变量, 尽量采用private
- 每一个变量声明/定义占一行(参数变量除外),如:int a;int b;比int a,b; 更容易读, 更容易查找bug
- 局部变量在使用前必须初始化,一般在声明时初始化
变量的声明要放在程序块的开始位置,如:
void myMethod() { |
一种例外情况是在for语句中,定义声明不仅不占一行,还在表达式内部,完全采用Eclips生成,如:
for(int i = 0; i<100; i++)
4. 数组的申明采用 <数据类型[] + 变量名>方式如:
5. char[] buffer; 而不是: char buffer[];
7.4方法
- 对成员方法,不要轻易的采用public的成员变量。主要的修饰符有public, private, protected, 无
- 空方法中方法声明和函数体不能写在一行,并用TODO标出。
推荐:
public void myFun(){ |
禁止:
public void myFun(){ } |
- 方法和方法之间空一行
- 方法参数尽量控制在5个以内,参数过多可封装成对象,以提高程序的可读性和可扩展性,参数分隔符后保持一个空格。
- 对于设计期间不需要子类来重载的类,尽量使用final
- 每个方法尽量代码行数尽量不要超过100行(有效代码行,不包括注释)
7.5书写规范
- 避免变量的定义与上一层作用域的变量同名。
-
在字符串变量在与字符串常数作比较时,字符串常数放在比较表达式的前面如:
String str="bbb";
if("aaa".equals(str)){
} -
Return语句中不要用小括号,除非使表达更清晰,如:
return (list.size() > 0 ? list.get(0) : null);
- return 语句中不要有复杂的逻辑计算
- switch语句,需要一个缺省的分支
8.其他
8.1工程规范
- 禁用System.out.println()进行调试信息的输出,而采用统一Logger4j作为日志输出工具。要根据情况分debug、info、warn、error等信息。
- 要保证调试信息清晰准确,禁止输出"----------------------------"、"---111111111111111--"、"555555555555555"等随意的字符串。
- 对所有的错误代码进行全局唯一编号,格式:GBQ-1005 表示"GBQ系统的1005号错误"
8.2目录结构
目录 | 说明 | ||
ProjectName | 项目名称 | ||
/build | 构建目录 | ||
/classes | 类构建目录 | ||
/src | Java源文件目录,各种配置文件存放根目录 | ||
/web | Web目录 | ||
/common | 公用跳转页面,如404.jsp | ||
/css | css文件目录 | ||
/decorators | 公用vm装饰页面 | ||
/gcp | 项目页面存放目录 | ||
/images | 图片存放目录 | ||
/script | Js脚本存放目录 | ||
/WEB-INF | Web配置文件,lib库 |
8.3JavaBean
- 一个javaBean类必须有一个不带有参数的公用构造器。
- 一个javaBean类不应有公共实例变量
- 类变量都为private通过getXxx和setXxx
8.4单元测试规范
- 关键代码(public方法、对外接口)必须进行单元测试。
- 关键代码的单元测试必须95%的覆盖。
- 测试包名:在原包后增加.test后缀(参考spring源码)。
- 测试类名:比如原类为BusinessServiceImpl,则测试类名为:TestBusinessServiceImpl
8.5技巧经验
- 当API会面对不可知的调用者时,方法需要对输入参数进行校验,如不符合则抛出IllegalArgumentException 。
- 在数组中的元素(如String [1]),如果不再使用需要设为NULL,避免内存泄漏。因此直接用Collections类而不要使用数组。
- 在不需要封闭修改的时候,尽量使用protected 而不是 private,方便子类重载。
- 变量,参数和返回值定义尽量基于接口而不是具体实现类,如Map map = new HashMap();
- 和金额相关时,使用BigDecimal,而不是float
- 重新抛出的异常必须保留原来的异常,即throw new NewException("message", e); 而不能写成throw new NewException("message")。
- 异常要么处理,要么抛出,不允许空的catch块。
- 重载方法必须使用@Override,可避免父类方法改变时导致重载函数失效。
- 不需要关心的warning信息可以用@SuppressWarnings("unused"), @SuppressWarnings("unchecked"), @SuppressWarnings("serial") 注释。
- 如果方法返回值类型是集合(List,Map,Set….)或数组,且记录为空的时候,返回空的集合或数组,不要返回Null。