【强制】:任何时候、任何情况下都不打折扣,必须遵守,必须执行。不遵守会严重影响代码规范
【更推荐】:一般情况下都应该遵守,是更推荐的做法。遵守会显著提升代码规范
【参考】:仅作为参考建议,不做要求
命名规范
1.【强制】代码中的任何命名一律不能以下划线或者美元符号开始,也不能作为结束。
说明:Java程序员的代码中是很少见下划线和美元符号的,建议即便是命名中间也尽量不要使用
反例:_name、Student_、$name、name$
2.【强制】代码中任何命名一律禁止使用拼音、或者拼音和英文混合的形式,更禁止直接使用中文。
说明:有些拼音已经成为国际通用的除外:beijing、alibaba、baidu、taobao等
反例:class 长方形、xuesheng [学生] 、getZuiDaZhi [最大值]
3.【强制】类、接口、注解等引用数据类型的名字一律使用大驼峰式。
说明:本身就是缩写的词组除外:DO、UID、VO、DAO等
正例:UserDO、Student、Test、XmlService
反例:UserDo、student、test、XMLService
4.【强制】方法名、变量名(包括局部变量、成员变量等)都一律使用小驼峰式。
说明:ID虽然也是缩写词组,但是很多时候大家还是喜欢将它作为一个单词用
正例:localValue、stu、test、userId
反例:LocalValue、Stu、Test、userID
5.【强制】包名统一使用小写,"."分隔符之间有且仅有一个自然语义的英语单词。包名一般以反写公司域名为开头,包名的单词中如有单复数的概念,统一使用单数。
说明:在涉及公司名或特殊业务需求时,可以合理使用拼音
正例:比如工具类的包名应为:com.function.util(具体的工具类可以叫XxxUtils)
反例:Com.test、ceshi.gongju
6.【强制】在声明数组时,类型与中括号紧挨相连来表示数组,而不是将中括号放在变量名后面
说明:不要使用C语言的方式声明数组
正例:声明整型数组int[] arr;
反例:声明字符串类型数组String args[];
7.【强制】不要自创缩写,不要使用有歧义的缩写,不能一眼看出原意的缩写不要使用
反例:将“teacher”缩写成"tea",”condition“缩写”命名成 condi等
【更推荐】为了让代码能够直接通过类名、方法名、变量名等名称读懂,任何自定义编程元素在命名时,使用尽量完整的单词组合来表达其意,即便这会使命名很长也无所谓。
说明:一句话,起名字的时候害怕不能“见名知意”,但就是不害怕很长的名字。
正例:比如工具类中有多个获取最大值的方法,要通过方法名说清楚各自的区别。
getMaxValueByArray、getMaxValueByScanner等
反例:直接统统叫getMax、定义一个方法的局部变量叫a等
8.【强制】常量命名全部大写,单词间用下划线隔开,命名可以很长,但是不能不清不楚。
正例:MAX_STOCK_COUNT
反例:maxValue、MAX
9.【强制】在 long 或者 Long 赋值时,数值后使用大写的 L,不能是小写的 l,小写容易跟数字1混淆,可能会造成误解。
说明:Long a = 2l; 写的是数字的 21,还是 Long 型的 2L?
特殊要求
1.【更推荐】抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类的命名以它要测试的类的名称开始,以 Test 结尾;接口的实现类的命名可以用接口的名字加上后缀"impl",也可以加上前缀以示说明。
正例:AbstractPerson、StudentDaoImpl
2.【更推荐】布尔类型的变量,一律禁止使用is前缀的形式,否则会引起某些框架的解析错误
说明:对于成员变量isMale而言,它的get方法也会写成isMale()。对于某些RPC框架而言,会将该属性误解析为male而获取不到,这样就会抛出异常。
反例:最典型的就是定义性别时,使用“isMale”或者“isFemale”
注释规范
1.【更推荐】单行注释的双斜线与注释内容之间有且仅有一个空格。
说明:阿里巴巴的规范中,单行注释要求双斜线后面必须有且仅有一个空格。坊间传闻这是阿里的脚本检查代码格式时的要求,应该不太具有实际意义。实测下来,双斜线后加一个空格,注释的阅读性会更好,大家可以模仿一下。
// 这是示例注释,请注意在双斜线之后有一个空格 String str = "hello world!";
2.【更推荐】所有的类都必须添加创建者和创建日期,也要指明该类的大致设计思路和用途。
3.【更推荐】属性和方法如有必要添加注释,必须使用 Javadoc 规范,即使用文档注释/** 内容 */的形式,禁止使用单行/多行注释的形式。
说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE 中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高
阅读效率。
说明:关于文档注释的具体格式会在文档最后详细说明,请查看完规范再翻看。
4.【强制】方法内部如有说明注释的需求,请使用单行或者多行注释, 放在在被注释语句的上面而不是下面。
说明:注释语句注意与代码对齐。
最后关于注释的书写,提几点规范的要求:
1.注释力求写得清楚明白,某些专有名词使用英文,正常的注释文字还是用中文写更好。
2.解释代码有两个极端,一个是完全不写注释,另一个是写一大堆啰嗦的注释。实际上合理命名,结构标准的代码是可以自解释的,所以没有必要把注释写得特别详细以至于啰嗦,只需要关键位置说明就足够了。
3.代码中的注释是给自己看的,有注释的代码,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。所以写注释有两个要求:
第一:能够准确反应设计思想和代码逻辑;
第二:能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。
4.代码如果修改了,不要忘记修改相关的注释。
变量的使用
1.【强制】禁止在代码中使用任何魔法值,变量都应该预先定义再使用。
说明:所谓魔法值,是指在代码中直接出现的数值(尤其是字面值),离开这段代码完全不知道它的含义。
比如下列代码:
int [] array = new int[20]; for (int i = 0; i < 20; i++){ System.out.print(array[i]); }
代码中使用了字面值“20”,试想一下如果数组的声明和数组的遍历代码相距较远,就很难明白“20”的具体含义了。这个“20”实际上就是一个魔法值,使用魔法值会严重影响代码可读性,应该避免在程序中使用魔法值。
上述代码可改成:
int arrLength = 20; int [] array = new int[arrLength]; for (int i = 0; i < arrLength; i++){ System.out.print(array[i]); }
2.【强制】严禁在一行声明定义多个变量,尤其是类型混合定义。
【正例】
int size; int[] entity;
【反例】
int size, entity[]; int a, b;
说明:一行定义多个变量,看起来代码更短了,但实际上这是没必要的(多写一行不要钱)而且对于开发和维护来说,也属于制造麻烦。
3.【更推荐】在方法体中定义局部变量时, 要在使用的时候定义,而不是一股脑先定义再隔很长代码使用。
说明:有些程序员在写方法时,喜欢上来先把自己需要的局部变量定义好,等使用它们时可能已经隔了n行代码。这种做法,一方面导致后面可能忘记定义而重复定义变量,定义死变量;另一方面局部变量的定义和使用间隔过远,也不利于理解局部变量的含义。在JDK源码或者框架源码中,可以看到都是在需要使用变量的时候创建,或者在需要使用的前几行代码申明再去创建。
代码格式
【强制】任何二元、三目运算符的左右两边都应该加上空格,禁止直接连接变量。
说明:元、目指的是操作数。常见的二元运算符如赋值运算符、算术运算符、逻辑运算符等
正例:int a = 10;
反例:int a=10;
【强制】方法的参数在定义和传入时,多个参数逗号后边必须加空格,但是逗号前面不要加空格。
正例:method(args1, args2, args3)
3.【强制】大括号的使用约定。
如果是大括号内为空,则简洁地写成{}即可,不需要换行;
如果是非空代码块则:左大括号前不换行。左大括号后换行。右大括号前换行。右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。
4.【强制】左小括号和字符之间不出现空格,右小括号和字符之间也不出现空格,而左大括号前需要空格。
5.【强制】if/for/while/switch/do 等保留字与括号之间都必须加空格。
实际上在IDEA中编程,只需要使用快捷键 Clt + Alt + L 就可以自动格式化上述格式。建议编码时,写一段就按一下该快捷键格式化代码。
6.在 if/else/for/while/do 语句中必须使用大括号。即使只有一行代码,也要尽量避免采用下面的单行的编码方式:
if (condition) statements;
7.【更推荐】单个方法包括方法签名、结束右大括号、方法内代码、注释、空行、回车及任何不可见字符的总行数不超过 80 行。
正例: 代码逻辑中要理清主干和分支,个性和共性。分支逻辑提取出来作为额外的方法,使主干逻辑更加清晰。 共性逻辑也是一样抽取出共性方法,便于复用和维护代码。
oop规范
主要针对面向对象编程过程中,需要遵循的一些规范:
1.【强制】静态成员严禁使用对象引用访问,必须使用类名去访问。
2.【强制】只要是覆盖、重写自父类或接口的方法,必须使用 @Override 注解。
说明:该注解可以检查方法是否是重写自父类,避免错误的重写!
3.【强制】不要使用过时的类和方法,即被@Deprecated注解修饰的类和方法
4.【强制】 接口中定义的方法和属性禁止添加任何修饰符,一般来说不要接口中定义常量和实现方法
说明:接口中如果想要定义常量,肯定是与接口方法相关且是整个接口子类都会使用的基础常量。Java8之后接口允许定义default和static实现方法,但一般情况下都不建议定义,除非是对是对所有实现类都有价值的默认实现。
正例:接口方法签名 void methodName();
反例:接口方法签名 public abstract void methodName();
5.【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。
正例:"test".equals(object);
反例:object.equals("test");
说明:如果是两个引用判断对象相等,推荐使用 java.util.Objects下的 equals 方法(JDK7 引入的工具类)
6.【强制】包装类型对象之间比较值的大小,一律使用equals,禁止使用“==”
说明:在-128 至 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用已有对象。
这个区间内的 Integer 值可以直接使用 “==” 进行比较值大小。
但是这个区间之外的所有数值包装类对象,都会在堆上产生,并不会复用已有对象,这是一个大坑。
建议都使用 equals 方法来比较值大小,避免考虑取值范围的问题~
7.在定义类的成员时:
【强制】先定义成员变量,再定义构造方法,成员方法放在最后面
【更推荐】在成员变量、构造方法和成员方法的各自区域内,成员的定义顺序是:先定义公有成员,而后是受保护成员,私有成员放在最后面。
说明:公有成员是需要提供外部使用的成员,是最受关注的,放在最上面展示最好。受保护成员虽然只对子类开放,但也是关键成员需要被外部访问,放在public下面最好。最后面放私有成员,因为外部一般不需要特别关注私有成员,那就藏到最后面吧。
【更推荐】接上一条,在定义方法时,如果类中有多个构造方法、多个同名成员方法,那些这些方法应该按照顺序放在一起,以方便阅读。
【参考】类中如果有getter/setter方法,因为它们一般都是给框架自动调用的,格式也是固定的,价值是比较小的,可以放在类体的最后面。
在给类的成员设置访问权限的时候,应该从严(尽量设置private):
8.【强制】如果不允许外部直接通过new创建对象,必须私有化构造方法,也不允许有默认构造方法。
说明:典型的像工具类中,工厂设计模式中
【强制】类成员方法只在类内部使用时,必须私有化。
说明:中间方法私有化
【更推荐】其余成员变量,静态成员变量,方法只要能够确定不会在类外部使用,一律设置为private。普通成员如有子类使用的需求,设置为protected。静态成员变量还最好考虑能不能设置为final
说明:设置权限时要尽量“吝啬”,能不给的权限就不给,能私有化就私有化。某个结构,它的权限越小,修改起来就越容易。比如一个私有的方法,删了就删了,最多对类的内部造成一些影响,排查起来很容易。但如果是一个public方法,我想你动它的时候心里也要三思吧~
9.【更推荐】一个方法只需要做它应该做的事情,不要为了偷懒让它“身兼多职”。
具体来说:
构造方法就是初始化对象、完成类的成员变量赋值,不要在里面加入业务逻辑代码。如果初始化对象依赖于复杂的业务逻辑,必须将业务代码放入init方法,从而达到复用代码,优化代码逻辑的目的
toString方法直接用idea自带模板生成,不要加入其它业务逻辑
getter/setter方法同样idea自动生成,不要加入其它业务逻辑
其它方法也是一样,遵循“专人专用”的原则,一个方法只需要完成它需要完成的功能即可,不要冗余。