Coding 规范
文章目录
- Coding 规范
- 一.文件规范
- 1.1 声明
- 1.2 缩进
- 1.3 空行
- 1.4 空格
- 1.5 对齐
- 1.6 小括号
- 1.7 花括号
- 1.8 代码长度
- 二.命名规范
- 2.1 命名总则
- 2.2 命名空间
- 2.3 类与接口
- 2.4 方法命名
- 2.5 属性命名
- 2.6 常量命名
- 2.7 变量命名
- 三.语句规范
- 3.1 语句总则
- 3.2 循环语句
- 3.3 Switch-case
- 四.编码格式
- 五.开发技巧
一.文件规范
1.1 声明
每行只能声明一个变量,如:
// indentation level int level;
// size of table
int size;
禁止
int level, size;
1.2 缩进
- 每个缩进单位为4个英文空格,不要在代码中使用Tab字符,可以在开发工具中将tab键设置为4个字符,idea设置方式如下
- 按层级缩进,缩进层级不能超过5层,否则需要拆分函数
1.3 空行
使用一个空行情况:
- 两个方法之间
- 方法内的局部变量和方法的第一条语句之间
- 块注释或单行注释之前
- 一个方法内的两个逻辑段之间,用以提高可读性
两个空行使用情况:
- 一个源文件的两个片段(section)之间
- 类声明和接口声明之间
1.4 空格
需要增加空格的地方有:
情形 | ** 示例** |
---|---|
在大多数运算符之前和之后 | 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) |
1.5 对齐
- 当方法参数过多时当在每个参数后(逗号后)换行并对齐。
- 当控制或循环中的条件比较长时当换行(操作符前)、对齐并注释各条件。
- 变量定义最好通过添加空格形成对齐,同一类型的变量应放在一起。
1.6 小括号
- 多个条件判断时,推荐增加小括号增加可读性
例如:
if (((a - b) << 2) > ((c - d) >> 4)) {
// do…
}
- 尽量不要在返回语句中使用()
1.7 花括号
-
{} 中的语句应该单独作为一行左
-
括号"{“当紧跟其语句后(即:在它后面换行),右括号”}"永远单独作为一行且与其匹配行对齐,并尽量在其后说明其匹配的功能模块。如:
public String getFirstNode (List<String> nodeList) { if (nodeList != null && nodeList.size() > 0) { return nodeList.get(0); } else { return null; } }
1.8 代码长度
- 单个方法的有效代码长度当尽量控制在100行以内(不包括注释行)
- 单个类的长度包括注释行不超过1500行。
二.命名规范
Pascal命名法:每个单词的首字母都大写。如:BackColor
Camel 命名法(驼峰命名法):首字母小写,后面每个单词的首字母都大写。如:backColor
Underline 命名法(下划线命名法):单词中间用下划线分割。如:string user_name;
2.1 命名总则
- 使用可以准确说明变量/字段/类/接口/包等的完整的英文描述符。例如,采用类似firstName,listAllUsers这样的名字,严禁使用汉语拼音及不相关单词命名。
- 采用该领域的术语。如果用户称他们的"客户" (clients) 为"顾客" (customers),那么就采用术语 Customer 来命名这个类,而不用 Client。
- 尽量少用缩写,但如果一定要使用,当使用公共缩写和习惯缩写等,如实现(implement)可缩写成impl,严禁滥用缩写。
- 避免使用长名字(最好不超过 25 个字母)。
- 避免使用相似或者仅在大小写上有区别的名字。
- 避免使用数字,如:map2map。
- 命名时应使用复数来表示它们代表多值,如:orderItems。
2.2 命名空间
- Java文件名所有单词首字母大写。
- 包名一般以项目或模块名命名,少用缩写和长名,一律小写。
- 不要用java, javax作为自定义包的前缀
2.3 类与接口
- 类的名字必须由大写字母开头而其他字母都小写的单词组成,对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母,一般使用名词命名。
- 接口的第一个字符用"I"开头,Service结尾,实现类的命名统一以"ServiceImpl"结尾。
2.4 方法命名
-
方法命名多为动词结构
-
采用有符合问题域意义的单词或单词组合。第一个单词常用一个动词,采用小写,后续的每个单词采用首字母大写,其余小写(特殊字除外如URL),没有特别理由不用下划线作为分隔符
-
在Java中对属性方法命名遵循JavaBean的标准:
getter,setter方法:最好使用@Data
注解 -
构造方法的命名与类名一致
-
取值使用get前缀,设值使用set前缀,判断类使用is(has)前缀,查询类使用query或find前缀(不建议get),修改类使用modify前缀(不建议update),删除类使用delete前缀。例:
getName() setSarry() isLogon() queryUserCount() modifyUserInfo() deleteUser() findByXXX()//获取单条记录的 listByXXX()//获取List集合的 pageXXX()//分页查询的
2.5 属性命名
- javabean属性命名尽量使用常规的驼峰式命名规则
- 属性名第一个单词尽量避免使用一个字母:如eBook, eMail。
- boolean属性名避免使用 “is” 开头的名称,因为javabean规范的boolean取值操作是isXXX
2.6 常量命名
- 采用完整的英文大写单词,在词与词之间用下划线连接,如:DEFAULT_VALUE。
- 命名尽量简短,不要超过16个字符
- 同一组的常量可以用常量类封装在一起,便于引用和维护
2.7 变量命名
-
变量的命名包括实例变量,静态变量,函数参数的命名。
-
变量的名字必须小写字母开头,后面的单词用大写字母开头,其余小写(特殊单词除外,如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等来命名。
-
集合命名:
-
用名词加集合名称的方式来命名,第一个单词首字母小写,如:
List<User> userList = new ArrayList<User>(); Map<String, User> userMap = new HashMap<String, User>();
-
禁止使用单个字母如l,m来命名。
-
三.语句规范
3.1 语句总则
-
统一使用IDEA格式化工具进行格式化,默认快捷键:Ctrl+ALT+L
-
尽量避免强制类型转换。如果不得不做类型转换,尽量用显式方式。
-
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的代码很短,这时候要调整结构
-
每一行最多包含一条语句。
3.2 循环语句
- 务必检查,杜绝死循环
- 即使循环体只有一条语句,也要用花括号括起
- 尽量不用空语句,特殊情况用到空语句,写好注释,告诉读者这不是bug
- 循环中禁止使用访问数据库的操作,循环内部如果需与数据库交互,而应提前一次性读取出。(重点注意)
3.3 Switch-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分支。
四.编码格式
- 一个程序文件最好不要超过1000行
- 尽可能缩小对象的作用域,这样对象的可见范围和生存期也都会尽可能地小
- 一个方法所完成的功能要单一,不同的功能封装为不同的方法.
- 如果对象在某个特定范围内必须被清理(而不是作为垃圾被回收),请使用带有finally子句的try块,在finally子句中进行清理。
- 在处理可变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)的形式进行构造 - 方法参数尽量控制在5个以内,参数过多可封装成对象,以提高程序的可读性和可扩展性,参数分隔符后保持一个空格。
- 禁用System.out.println()进行调试信息的输出,而采用统一slf4j
五.开发技巧
- 当API会面对不可知的调用者时,方法需要对输入参数进行校验,如不符合则抛出IllegalArgumentException 。
- 在数组中的元素(如String [1]),如果不再使用需要设为NULL,避免内存泄漏。因此直接用Collections类而不要使用数组。
- 在不需要封闭修改的时候,尽量使用protected 而不是 private,方便子类重载。
- 变量,参数和返回值定义尽量基于接口而不是具体实现类,如Map map = new HashMap();
- 和金额相关时,使用BigDecimal,而不是float
- 异常要么处理,要么抛出,不允许空的catch块。
- 重载方法必须使用@Override,可避免父类方法改变时导致重载函数失效。
- 不需要关心的warning信息可以用@SuppressWarnings(“unused”), @SuppressWarnings(“unchecked”), @SuppressWarnings(“serial”) 注释。
- 如果方法返回值类型是集合(List,Map,Set….)或数组,且记录为空的时候,返回空的集合或数组,不要返回Null。