JAVA代码规范
1. 前言................................................................................................................................................................ 2
2. 源文件规范................................................................................................................................................ 2
2.1 文件名............................................................................................................................................ 2
2.2 文件编码 UTF-8..................................................................................................................... 2
2.3 源文件结构................................................................................................................................. 3
2.4 文件长度...................................................................................................................................... 3
2.5 import语句................................................................................................................................. 3
3. 排版格式..................................................................................................................................................... 3
3.1 大括号............................................................................................................................................ 3
3.1.1 使用大括号.................................................................................................................. 3
3.1.2 非空块............................................................................................................................. 3
3.1.3 空块.................................................................................................................................. 4
3.2 缩进(identation)............................................................................................................... 4
3.3 行宽(line width)................................................................................................................ 4
3.4 自动换行...................................................................................................................................... 4
3.4.1 什么时候自动换行.................................................................................................. 4
3.5 空行................................................................................................................................................. 5
3.6 使用Eclipse的formatter................................................................................................. 5
4. 命名规范..................................................................................................................................................... 5
4.1 包名................................................................................................................................................. 5
4.2 类名/接口名.............................................................................................................................. 6
4.3 方法名............................................................................................................................................ 6
4.4 常量名............................................................................................................................................ 6
4.5 变量名............................................................................................................................................ 6
4.6 局部变量和类属性重名...................................................................................................... 6
4.7 长整形数值以大写'L'结尾................................................................................................. 6
4.8 SpringBean命名..................................................................................................................... 6
5. 注释规范..................................................................................................................................................... 7
5.1 实现注释(Implementation Comments).................................................................... 7
5.2 文档注释(Documentation Comments)..................................................................... 7
5.2.1 类注释............................................................................................................................. 7
5.2.2 方法注释........................................................................................................................ 8
5.2.3 类属性注释.................................................................................................................. 8
5.2.4 注释顺序........................................................................................................................ 8
6. 编程实践规范........................................................................................................................................... 8
6.1 度量................................................................................................................................................. 8
6.1.2 耦合度度量.................................................................................................................. 8
6.1.3 方法度量........................................................................................................................ 9
6.1.4 其他度量........................................................................................................................ 9
6.2 equals.............................................................................................................................................. 9
6.2.1 覆盖equals.................................................................................................................. 9
6.2.2 字符串相等............................................................................................................... 10
6.2.3 BigDecimal.equals().............................................................................................. 10
6.2.4 字符串equals的调用者................................................................................... 10
6.3 性能.............................................................................................................................................. 10
6.3.1 不要使用+拼接字符串....................................................................................... 10
6.3.2 StringBuffer和StringBuilder........................................................................ 10
6.3.3 类内部属性............................................................................................................... 10
6.3.4 Map元素的遍历..................................................................................................... 10
6.4 线程.............................................................................................................................................. 11
6.4.1 禁止将Calendar用做类的静态变量........................................................ 11
6.4.2 禁止将DateFormat用做类的静态变量................................................. 11
6.4.3 不允许在持有锁的时候调用Thread.sleep()....................................... 11
6.4.4 不允许在Boolean对象上使用synchronized关键字................... 11
6.5 异常.............................................................................................................................................. 11
6.5.1 不要吞掉异常.......................................................................................................... 11
6.5.2 不要嵌套try语句................................................................................................. 11
6.6 日志.............................................................................................................................................. 12
6.6.1 打印异常堆栈.......................................................................................................... 12
6.6.2 logger.debug.............................................................................................................. 12
6.6.3 System.out、e.printStackTrace()................................................................. 12
1. 前言
谨以此规范,望能给java开发带来一个规范的环境,规范java代码,提高代码质量, 增加代码可读性,从最基本的代码规范开始,不断增强java开发人员的技能。
2. 源文件规范
2.1 文件名
源文件以最顶层的类名来命名,大小写敏感,文件扩展名为.java
2.2 文件编码 UTF-8
源文件要求编码格式为UTF-8
2.3 源文件结构
一个源文件包含(按顺序地):
许可和版权信息(如有需要)
package语句
import语句
一个顶级类(只有一个)
以上每个部分之间用一个空行隔开
2.4 文件长度
按照sun的规范,代码行数尽量不要超过2000行
2.5 import语句
禁止使用通配的方式import,列如:import java.utils.*
3. 排版格式
3.1 大括号
3.1.1 使用大括号
大括号与if, else, for, do, while语句一起使用,即使只有一条语句(或是空),也应该把大括号写上。
比如:
if(a==b) {
return true;
}
3.1.2 非空块
对于非空块和块状结构,大括号遵循Kernighan和Ritchie风格 (Egyptian brackets):
l 左大括号前不换行
l 左大括号后换行
l 右大括号前换行
l 如果右大括号是一个语句、函数体或类的终止,则右大括号后换行; 否则不换行。例如,如果右大括号后面是else或逗号,则不换行。
3.1.3 空块
一个空的块状结构里什么也不包含,大括号可以简洁地写成{},不需要换行。例外:如果它是一个多块语句的一部分(if/else 或 try/catch/finally) ,即使大括号内没内容,右大括号也要换行。
比如:
void doNothing() {}
3.2 缩进(indentation)
每当开始一个新的块,缩进增加4个tab,当块结束时,缩进返回先前的缩进级别。缩进级别适用于代码和注释。
3.3 行宽(line width)
行宽采用120字符的限制
3.4 自动换行
一般情况下,一行长代码为了避免超出列限制(120个字符)而被分为多行,我们称之为自动换行(line-wrapping)。
3.4.1 什么时候自动换行
自动换行的基本准则是:更倾向于在更高的语法级别处断开。
l 如果在非赋值运算符处断开,那么在该符号前断开(比如+,它将位于下一行)。这条规则也适用于以下“类运算符”符号:点分隔符(.),类型界限中的&(<T extends Foo & Bar>),catch块中的管道符号(catch(FooException | BarException e)
l 如果在赋值运算符处断开,通常的做法是在该符号后断开(比如=,它与前面的内容留在同一行)。这条规则也适用于foreach语句中的分号。
l 方法名或构造函数名与左括号留在同一行。
l 逗号(,)与其前面的内容留在同一行。
3.5 空行
空行将逻辑相关的代码段分隔开,以提高可读性。
下列情况应该总是使用两个空行:
l 一个源文件的两个片段(section)之间
l 类声明和接口声明之间
下列情况应该总是使用一个空行:
l 两个方法之间
l 方法内的局部变量和方法的第一条语句之间
l 块注释或单行注释参加注释规范
l 一个方法内的两个逻辑段之间,用以提高可读性
3.6 使用Eclipse的formatter
1. 下载Eclipse的formatter文件:http:leweg.com/fomatter.xml
2. 导入eclipse: Window → Preferences → Java → Code Style → Formatter → Import →选择文件
3. 格式化
a) 手动格式化: 右键Java文件选择Source→Format或者通过快捷键 Ctrl + Shift + F来对文件进行格式化
b) 自动格式化: Window→ Preferences -→ Java -→ Editor -→ Save Actions,先勾选"Perform the selected actions on save",再勾选"Formatsource code"
4. 命名规范
4.1 包名
包名全部小写,包名的前缀总是一个顶级域名,通常是com, edu, gov, mil, net, org, 或1981年ISO 3166标准所指定的标识国家的英文双字符代码。包名的后续部分根据不同机构各自内部的命名规范而不尽相同。
一般规范:com.leweg.系统名.模块名...
4.2 类名/接口名
类名都以UpperCamelCase风格编写,通常为名词,尽量避免不被广泛使用的缩写.
测试类的命名以它要测试的类的名称开始,以Test结束
对业务接口(Service)的实现类,以接口的名称开始,以Impl结尾
4.3 方法名
方法名都以UpperCamelCase风格编写,通常为动词。
4.4 常量名
全部字母大写,用下划线分隔单词。
普遍认为final定义的变量即为常量,但并不绝对,只有认为永远不会改变的才为常量
比如logger, 我们一般不认为是常量:
static final Logger logger = Logger.getLogger(MyClass.getName());
建议: 因为一些代码检查工具, 比如sonar会检查final的常量名必须为大写,可以考虑logger不加final
4.5 变量名
以lowerCamelCase风格编写
4.6 局部变量和类属性重名
局部变量和类属性重名,虽然是合法的,但是如果没有IDE工具颜色标识,会让人误解。
4.7 长整形数值以大写'L'结尾
对于长整形数值来说,以小写'l'结尾,很容易误看为1,所以应该使用大写'L'。
long userId=23l; // 使用了小写l
long userId=23L; // 使用大小L
4.8 Spring Bean命名
使用类名本身, 并且第一个字母小写
5. 注释规范
良好的注释习惯,是一个优秀的开发人员需要具备的基本素养。
Java的注释分两种,实现注释(implementationcomments)和文档注释(document comments)。
实现注释使用/*...*/和//界定,文档注释使用/**...*/界定。
实现注释用以注释代码或者实现细节,文档注释从实现自由 (implementation-free)的角度描述代码的规范。
文档注释可以通过javadoc工具生成HTML文件。
5.1 实现注释(Implementation Comments)
使用/*...*/来进行块注释
使用//进行行注释
5.2 文档注释(Documentation Comments)
文档注释描述Java的类、接口、构造器,方法,以及字段(field)。每个文档注释都会被置于注释定界符/**...*/之中,一个注释对应一个类、接口或成员。该注释应位于声明之前:
/**
*The Example class provides ...
*/
public class Example { ...
5.2.1 类注释
/**
*Description:类功能概述×××××××
*
*Copyright:
*@author
*@version @date
*/
5.2.2 方法注释
/**
* 方法说明×××××××
*
* @param 参数说明
* @param XXXXX
* @throws Exception
*/
5.2.3 类属性注释
private Class instance;
/** 可以在javadoc中生成 **/
5.2.4 注释顺序
标准的Javadoc注释按以下顺序出现:@param, @return, @throws, @deprecated, 前面这4种标记如果出现,描述都不能为空。
6. 编程实践规范
6.1 度量
6.1.2 耦合度度量
l DAC度量值不要不大于7
DAC(Data Abstraction Coupling)数据抽象耦合度是描述对象之间的耦合度的一种代码度量。DAC度量值表示一个类中有实例化的其它类的个数。
l CFO度量值不要不大于20
CFO(Class Fan Out)类扇出是描述类之间的耦合度的一种代码度量。CFO度量值表示一个类依赖的其他类的个数。
6.1.3 方法度量
l 方法(构造器)参数在5个以内
太多的方法(构造器)参数影响代码可读性。考虑用值对象代替这些参数或重新设计。
l 方法长度150行以内
l CC 度量值不大于10(III )
CC(Cyclomatic Complexity)圈复杂度指一个方法的独立路径的数量,可以用一个方法内if,while,do,for,catch,switch,case,?:语句与&&,||操作符的总个数来度量。
l NPath度量值不大于200
NPath度量值表示一个方法内可能的执行路径的条数。
6.1.4 其他度量
l 布尔表达式中的布尔运算符(&&,||)的个数不超过3个
l if语句的嵌套层数3层以内
l 匿名内部类20行以内
太长的匿名内部类影响代码可读性,建议重构为命名的(普通)内部类。
6.2 equals
6.2.1 覆盖equals
l 覆盖equals方法且没有在其中最终调用super.equals()的类,必须同时也覆盖hashCode方法 ,hashCode的设计要求必须满足“通过equals判断相等的两个对象,hashCode必须相等”。
l equals()和hashCode()通常都是成对出现,如果我们只覆盖其中的一个方法,可能会导致潜在错误,如向Collection.中添加此类对象。
l equals方法中应判断传入对象是否为null。这是equals方法的基本设计要求。
6.2.2 字符串相等
使用equals来判断字符串相等,而非==
6.2.3 BigDecimal.equals()
不要使用.equals()判断两个java.math.BigDecimal变量是否相等,对BigDecimal类型,只有这两个变量的值和精度完全一致才相等,如2.0和2.00这两个BigDecimal值是不相等的,判断java.math.BigDecimal数学相等,需要使用.compareTo()方法。
6.2.4 字符串equals的调用者
当.equals()的参数是String字符串时,应该考虑将String字符串作为.equals()的调用者,而 expression为函数参数,这样可以预防NullPointerException。
6.3 性能
6.3.1 不要使用+拼接字符串
使用+拼接字符串,每次拼接都会产生新的字符串对象,使用StringBuffer或者StringBuilder来拼接字符串。
6.3.2 StringBuffer和StringBuilder
StringBuffer为线程安全, StringBuilder线程不安全,StringBuilder性能略微高些
6.3.3 类内部属性
如果在类的内部如果想获取属性值时,使用了get方法,且该get方法只包含返回逻辑,仅仅返回属性值,这个时候应该考虑直接访问变量,这样会有微小的性能提升。
6.3.4 Map元素的遍历
尽量使用entrySet,而不是keySet
6.4 线程
6.4.1 禁止将Calendar用做类的静态变量
Calendar为非线程安全的,在多线程环境下会产生问题
6.4.2 禁止将DateFormat用做类的静态变量
DateFormat为非线程安全的,在多线程环境下会产生问题
6.4.3 不允许在持有锁的时候调用Thread.sleep()
在持有锁的时候调用Thread.sleep()很可能导致等待该锁的其它线程被长时间的挂起,从而严重影响程序性能。
6.4.4 不允许在Boolean对象上使用synchronized关键字
由于Boolean对象通常仅以两个全局的常型实例出现,在其上使用synchronized关键字可能导致与其它共用该常型实例的完全不相关的代码形成互斥关系。
6.5 异常
6.5.1 不要吞掉异常
捕获异常后,不允许不做任何处理,要么打印日志,要么抛出新的异常,重新抛出的异常必须保留原来的异常,即throw new NewException("message", ex),不应该写成throw new NewException("message")。
6.5.2 不要嵌套try语句
在一个try语句中再嵌套一个try语句,这样的代码让人迷惑,应该考虑try合并。
6.6 日志
6.6.1 打印异常堆栈
当打印异常日志的时候,使用logger.xxxx(‘出现异常’, exception),如果不指定第二个参数,异常堆栈不会打印出来。
6.6.2 logger.debug
当有连续的logger.debug调用,logger.debug参数存在字符串拼接或者方法调用,在logger.debug之前使用logger.isDebugEnable()来做判断
6.6.3 System.out、e.printStackTrace()
禁止在代码中使用System.out.println(),e.printStackTrace(),必须使用logger打印信息。
参考文献:
Java官方代码规范文档:
http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html
Google编码规范:
https://google-styleguide.googlecode.com/svn/trunk/javaguide.html