Java开发手册版本号制定团队更新日期备注1.0.0浅墨公司技术团队2017.7.28一、编程规约(一)命名规约1.代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例:_name/__name/$Object/name_/name$/Object$2.代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。hangzhou等国际通用的名称,可视同英文。反例:DaZhePromotion[打折]/getPingfenByName()[评分]/int某变量=3正例:discount[打折]/scoreByName()[评分]/intnumber=33.类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO/BO/DTO/VO等。正例:MarcoPolo/UserDO/XmlService/TcpUdpDeal/TaPromotion反例:macroPolo/UserDo/XMLService/TCPUDPDeal/TAPromotion4.方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格,必须遵从驼峰形式。正例:localValue/getHttpMessage()/inputUserId5.常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。正例:MAX_STOCK_COUNT反例:MAX_COUNT6.抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开始,以Test结尾。进行全测试或包测试的类名使用“AllTest”或“包名+Test”。7.中括号是数组类型的一部分,数组定义如下:String[]args;反例:使用Stringargs[]的方式来定义。8.POJO类中布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误。反例:定义为基本数据类型BooleanisSuccess;的属性,它的方法也是isSuccess(),RPC框架在反向解析的时候,“以为”对应的属性名称是success,导致属性获取不到,进而抛出异常。9.包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。正例:应用工具类包名为com.alibaba.open.util、类名为MessageUtils(此规则参考spring的框架结构)10.杜绝完全不规范的缩写,避免望文不知义。反例:AbstractClass“缩写”命名成AbsClass;condition“缩写”命名成condi,此类随意缩写严重降低了代码的可阅读性。11.如果使用到了设计模式,建议在类名中体现出具体模式。说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计思想。正例:publicclassOrderFactory;publicclassLoginProxy;publicclassResourceObserver;12.接口类中的方法和属性不要加任何修饰符号(public也不要加),保持代码的简洁性,并加上有效的Javadoc注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。正例:接口方法签名:voidf();接口基础常量表示:StringCOMPANY=qianmo;反例:接口方法定义:publicabstractvoidf();说明:JDK8中接口允许有默认实现,那么这个default方法,是对所有实现类都有价值的默认实现。13.接口和实现类的命名规则:对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别。注意:接口名的前面加上“I”。正例:CacheServiceImpl实现ICacheService接口。14.枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。说明:枚举其实就是特殊的常量类,且构造方法被默认强制是私有。正例:枚举名字:DealStatusEnum,成员名称:SUCCESS/UNKOWN_REASON。15.返回boolean型变量的方法,使用可明确指示真伪值的名字16.注意英语的反义词的对称性,作用/机能等相对的方法定义方法名时,请注意英语反义词的对称性。正例:send和receive、top和bottom、width和height等。17.long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。说明:Longa=2l;写的是数字的21,还是Long型的2?18.各层命名规约:A)controller/service/dao/sqlXml层方法命名规约1)获取单个对象的方法用get做前缀。2)获取多个相同对象的方法用list做后缀。3)获取统计值的方法用count做前缀。4)插入的方法用insert做前缀。5)删除的方法用delete做前缀。6)修改的方法用update做前缀。7)当拥有重要条件时使用By做连接,如:listUserById,deleteUserById8)当拥有多个不同对象时使用With做连接,如:listUserWithUserInformation9)特殊业务特殊命名10)如果当前所属后台方法加ForBack其他类似,如:listUserForBackB)领域模型命名规约1)数据对象:xxxDO,xxx即为数据表名。2)数据传输对象:xxxDTO,xxx为业务领域相关的名称。3)展示对象:xxxVO,xxx一般为网页名称。4)POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。C)jsp页面方法命名规约1)不同区块在方法名加前缀。正例:backerAccount.jsp/businessFeedback.jsp2)同一区块不同作用在方法名加后缀。正例:helpBusinessAdd.jsp/helpBusinessDetails.jsp/helpBusinessUpdate.jsp(二)格式规约1.大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果是非空代码块则:1)左大括号前不换行。2)左大括号后换行。3)右大括号前换行。4)右大括号后还有else等代码则不换行;表示终止右大括号后必须换行。2.左括号和后一个字符之间不出现空格;同样,右括号和前一个字符之间也不出现空格。详见第5条下方正例提示。3.if/for/while/switch/do等保留字与左右括号之间都必须加空格。4.任何运算符左右必须加一个空格。说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号、三目运行符等。5.缩进采用4个空格,禁止使用tab字符。说明:如果使用tab缩进,必须设置1个tab为4个空格。IDEA设置tab为4个空格时,请勿勾选Usetabcharacter;而在eclipse中,必须勾选insertspacesfortabs。正例:(涉及1-5点)publicstaticvoidmain(String[]args){//缩进4个空格Stringsay=hello;//运算符的左右必须有一个空格intflag=0;//关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不需要空格if(flag==0){System.out.println(say);}//左大括号前加空格且不换行;左大括号后换行if(flag==1){System.out.println(world);//右大括号前换行,右大括号后有else,不用换行}else{System.out.println(ok);//在右大括号后直接结束,则必须换行}}6.单行字符数限制不超过120个,超出需要换行,换行时遵循如下原则:1)第二行相对第一行缩进4个空格,从第三行开始,不再继续缩进,参考示例。2)运算符与下文一起换行。3)方法调用的点符号与下文一起换行。4)在多个参数超长,逗号后进行换行。5)在括号前不要换行,见反例。正例:StringBuffersb=newStringBuffer();//超过120个字符的情况下,换行缩进4个空格,并且方法前的点符号一起换行sb.append(zi).append(xin)....append(huang)....append(huang)....append(huang);反例:StringBuffersb=newStringBuffer();//超过120个字符的情况下,不要在括号前换行sb.append(zi).append(xin)...append(huang);//参数很多的方法调用可能超过120个字符,不要在逗号前换行method(args1,args2,args3,...,argsX);7.方法参数在定义和传入时,多个参数逗号后边必须加空格。正例:下例中实参的a,后边必须要有一个空格。method(a,b,c);8.没有必要增加若干空格来使某一行的字符与上一行的相应字符对齐。正例:inta=3;longb=4L;floatc=5F;StringBuffersb=newStringBuffer();说明:增加sb这个变量,如果需要对齐,则给a、b、c都要增加几个空格,在变量比较多的情况下,是一种累赘的事情。9.方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。说明:没有必要插入多行空格进行隔开。(三)控制语句1.在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。2.在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if(condition)statements;3.推荐尽量少用else,if-else的方式可以改写成:if(condition){...returnobj;}//接着写else的业务逻辑代码;说明:如果非得使用if()...elseif()...else...方式表达逻辑,请勿超过3层。4.除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。说明:很多if语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?正例://伪代码如下booleanexisted=(file.open(fileName,w)!=null)&&(...)||(...);if(existed){...}反例:if((file.open(fileName,w)!=null)&&(...)||(...)){...}5.循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的try-catch操作(这个try-catch是否可以移至循环体外)。6.方法中需要进行参数校验的场景:1)调用频次低的方法。2)执行时间开销很大的方法,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。3)需要极高稳定性和可用性的方法。4)对外提供的开放接口,不管是RPC/API/HTTP接口。5)敏感权限入口。7.方法中不需要参数校验的场景:1)极有可能被循环调用的方法,不建议对参数进行校验。但在方法说明里必须注明外部参数检查。2)底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错误不