【JAVA编码规范】JAVA编码规范,超级详细的JAVA编码规范,太棒了,值得你通读一遍

目录

.概述

1.1背景

1.2目的

1.3适用范围

1.4名词解释

1.5文档说明

2.文件规范

2.1文件编码

2.2文件命名

2.3配置文件的选择

3.排版风格

3.1总原则

3.2列宽/换行

3.3声明

3.4缩进

3.5空行

3.6空格

3.7对齐

3.8小括号

3.9花括号

3.10代码长度

4.命名规范

4.1命名总则

4.2命名空间

4.3类与接口

4.4方法

4.5参数

4.6属性

4.7常量

4.8变量

4.9集合

4.10异常

4.11控件

4.12关键字

4.13命名示例

5.语句规范

5.1语句总则

5.2循环语句

5.3Switch-case

6.注释规范

6.1注释总则

6.2文档注释

6.3屏蔽代码

6.4类注释

6.5函数注释

6.6代码注释

6.7变量注释

6.8修改别人的代码

6.9单行注释

6.10其他注释

7.编码格式

7.1基本原则

7.2类编码格式

7.3变量

7.4方法

7.5书写规范

8.其他

8.1工程规范

8.2目录结构

8.3JavaBean

8.4单元测试规范

8.5技巧经验


.概述

1.1背景

编码规范对于程序员而言尤为重要,有以下几个原因:

  1. 一个软件的生命周期中,80%的花费在于维护
  2. 几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护
  3. 规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的设计和代码
  4. 良好的编码规范可以有效避免一些低级错误

1.2目的

  1. 统一规范,方便阅读、维护,提高代码质量
  2. 统一格式,使代码度量更加精确,为公司软件过程体系优化打好基础。

1.3适用范围

全公司所有JAVA项目及程序

1.4名词解释

  1. Pascal命名法:每个单词的首字母都大写。如:BackColor
  2. Camel 命名法(驼峰命名法):首字母小写,后面每个单词的首字母都大写。如:backColor
  3. Underline 命名法(下划线命名法):单词中间用下划线分割。如:string user_name;
  4. 中划线命名法:所有字母均小写,单词中间用中划线"-"分割。如:user-list.jsp
  5. 匈牙利命名法:变量名=属性+类型+对象描述。如:btnUserName,只允许控件命名使用。

1.5文档说明

  1. 是在业界通用规范基础上结合公司现有规范制定的
  2. 符合主流IED工具,符合开发人员的大多数习惯
  3. 尽量减少规范的描述篇幅,使之易阅读

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 
.shtml    .vm    .ftl    .xml    .json         
.txt     .css   .JPG .png .gif

中划线命名法          

view-bundle.ftl 
bundle-context-osgi.xml                
user-list.json

2.3配置文件的选择

  1. .properties配置文件:可读性差、不容易扩展,中文还需要转码,不推荐使用。若配置内容特别少,只有单一格式的英文字母,则可以使用。
  2. .xml配置文件:结构化好、扩展性强、可自我校验,推荐使用。

3.排版风格

3.1总原则

  1. 采用eclipse作为开发工具,编码风格总体和eclipse编码风格一致。
  2. 写代码时,不必特意设定空格、对齐等;写完一个方法或一个类后,用eclipse的格式化工具完成格式化即可,快捷键:CTRL+Shift+F
  3. 注意:Eclipse格式化工具默认会进行空格、缩进排版,会自动在两个函数间加入空行,但不会自动修改函数体内的空行——即:函数体内语句间如果需要空行,则要手工加入。

3.2列宽/换行

  1. 每行代码的字符数不超过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, 
          String message, String errors) { 
     JSONObject obj = wrap(data, successs, message, errors); 
     obj.accumulate(RESULTS, results); 
     return obj; 
}

例2,操作符换前换行:

String finalMethodName = "init" + firstChar                                                        
         + invokeMethod.substring(1);

例3,属性操作符前换行:

char firstChar = Character.toTitleCase(invokeMethod                                        
         .charAt(0));

        3. 一条语句折行后, 应该比原来的语句再缩进4个空格,以便于阅读。

3.3声明

每行只能声明一个变量,如:

// indentation level                                                                                                   
int level;


// size of table 
int size;

禁止:

int level, size;                                                                                                          

3.4缩进

  1. 每个缩进单位为4个英文空格,不要在代码中使用Tab字符,可以在开发工具中将tab键设置为4个字符,eclipse设置缩进方法如下:

    WindowPreferencesjavacodestyleFormatter,然后点击edit按钮,在Indentation页签中的General Settings选项集里,将Tab policy由Tabs only改为Spaces only,并保持Indetation size和tab size为4, 最后在最上方的Profile name里任意输入字符,保存当前页设置即可

  2. 按层级缩进,缩进层级不能超过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)) 
例外:表示函数调用的括号不用加空格。如:getData(param1);

|, &, ||, && 前后

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对齐

  1. 当方法参数过多时当在每个参数后(逗号后)换行并对齐。
  2. 当控制或循环中的条件比较长时当换行(操作符前)、对齐并注释各条件。
  3. 变量定义最好通过添加空格形成对齐,同一类型的变量应放在一起。

3.8小括号

        1.  当不清楚是否应该加小括号时请添加小括号,否则很难看明白其含义。

推荐:

if (((a - b) << 2) > ((c - d) >> 4)) {                                                                       
     // do... 
}

不推荐:

if (a - b << 2 > c - d >> 4) {                                                                                
     //do... 
}

       2.  尽量不要在返回语句中使用()。

3.9花括号

{} 中的语句应该单独作为一行,左括号"{"当紧跟其语句后(即:在它后面换行),右括号"}"永远单独作为一行且与其匹配行对齐,并尽量在其后说明其匹配的功能模块。如:

public String getFirstNode(List nodeList) {                                                  
     if (nodeList != null && nodeList.size() > 0) { 
         return nodeList.get(0); 
     } else { 
        return null
     } 
}

3.10代码长度

  1. 单个方法的有效代码长度当尽量控制在100行以内(不包括注释行)
  2. 单个类的长度包括注释行不超过1500行。

4.命名规范

4.1命名总则

  1. 使用可以准确说明变量/字段/类/接口/包等的完整的英文描述符。例如,采用类似firstName,listAllUsers这样的名字,严禁使用汉语拼音及不相关单词命名。
  2. 采用该领域的术语。如果用户称他们的"客户" (clients) 为"顾客" (customers),那么就采用术语 Customer 来命名这个类,而不用 Client。
  3. 尽量少用缩写,但如果一定要使用,当使用公共缩写和习惯缩写等,如实现(implement)可缩写成impl,经理(manager)可缩写成mgr等,,严禁滥用缩写。
  4. 避免使用长名字(最好不超过 25 个字母)。
  5. 避免使用相似或者仅在大小写上有区别的名字。
  6. 避免使用数字,但可用2代替to,用4代替for,如:map2map。
  7. 命名时应使用复数来表示它们代表多值,如:orderItems。

4.2命名空间

  1. Java文件名所有单词首字母大写。
  2. 包名一般以项目或模块名命名,少用缩写和长名,一律小写。
  3. 不要用java, javax作为自定义包的前缀
  4. 基本包:com.glodon,所有包、文件都从属于此包。不得将类直接定义在基本包下。
  5. 每个产品/项目都有一个独立命名空间,如:com.glodon.xxx下xxx代表某个产品或产品缩写,全局唯一;禁止将类文件直接放在com.glodon.下。

4.3类与接口

类的名字必须由大写字母开头而其他字母都小写的单词组成,对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母,一般使用名词命名。

public abstract class AbstractWebService {                                                                  
      
}

接口的第一个字符用"I"开头,Service结尾,实现类的命名统一以"ServiceImpl"结尾。

public interface IUserInfoQryService{ 
 
}


public class UserInfoQryServiceImpl implements IUserInfoQryService{                        
   
}

4.4方法

  1. 方法命名多为动词结构
  2. 采用有符合问题域意义的单词或单词组合。第一个单词常用一个动词,采用小写,后续的每个单词采用首字母大写,其余小写(特殊字除外如URL),没有特别理由不用下划线作为分隔符
  3. 在Java中对属性方法命名遵循JavaBean的标准:
    getter方法:  get+属性名, 对boolean型采用is+属性名,有些特定的属性名用has, can代替is可能更好
    setter方法:  set+属性名
  4. 构造方法的命名与类名一致
  5. 取值使用get前缀,设值使用set前缀,判断类使用is(has)前缀,查询类使用query或find前缀(不建议get),修改类使用modify前缀(不建议update),删除类使用delete前缀等等。例:
     

getName() 
setSarry() 
isLogon() 
queryUserCount()                                                                       
modifyUserInfo() 
deleteUser()

      6. 获取单条记录的:findByXXX()

      7. 获取List集合的:listByXXX()

      8. 分页查询的:pageXXX()

4.5参数

使用有意义的参数命名,如果可能的话,使用和要赋值的字段一样的名字,并用this区分:

public void setSize(int size) {                                                                                
this.size = size; 
}

方法参数建议顺序:(被操作者,操作内容,操作标志,其他……) 例:

/** 
* 字符串替换 
@param sourceStr 源字符串 
@param oldStr 被替换的字符串 
@param newStr 替换为字符串 
*/ 
public void replace(String sourceStr, String oldStr, String newStr) {                          

4.6属性

以下规则概述属性的命名指南:

  1. javabean属性命名尽量使用常规的驼峰式命名规则
  2. 属性名第一个单词尽量避免使用一个字母:如eBook, eMail。
  3. boolean属性名避免使用 "is" 开头的名称,因为javabean规范的boolean取值操作是isXXX

4.7常量

  1. 采用完整的英文大写单词,在词与词之间用下划线连接,如:DEFAULT_VALUE
  2. 命名尽量简短,不要超过16个字符
  3. 同一组的常量可以用常量类封装在一起,便于引用和维护

4.8变量

  1. 变量的命名包括实例变量,静态变量,函数参数的命名。
  2. 变量的名字必须小写字母开头,后面的单词用大写字母开头,其余小写(特殊单词除外,如URL)
  3. 对不易清楚识别出该变量类型的变量应使用类型缩写作其前缀,如字符串使用strXXX,boolean使用isXXX,hasXXX等等。
  4. 命名尽量简短,不要超过16个字符
  5. 除了生命周期很短的临时变量外,避免采用单字符作为变量名,实例变量的命名不要用单字符。常用的单字符变量如整型用 i、j、 k、 m、 n字符型用c、d、 e,坐标用x、y、z。
  6. 不要用a、b、c、i、j、n等没有意义的变量命名;
  7. 不要怕麻烦,要使用带有意义的单词命名,如:userListSize、rowLength等来命名。

4.9集合

  1. 用名词加集合名称的方式来命名,第一个单词首字母小写,如:

    List userList = new ArrayList(); 
    Map userMap = new HashMap();                        

  2. 禁止使用单个字母如l,m来命名。
  3. 数组应该总是用下面的方式来命名:

4.10异常

  1. 异常类名由表示该异常类型的单词和Exception组成,如ActionException。
  2. 异常实例一般使用e、ex等,在多个异常时使用该异常名或简写加E,Ex等组成,如:SQLEx

4.11控件

应采用完整的英文描述符命名组件,遵循匈牙利命名法则。如:btnOK,lblName。

4.12关键字

不要使用语言本身已经占用的关键字或保留字命名。

    abstract        default        if        private        this    
    boolean        do        implements        protected    throw 
    break         double        import        public        throws         
    byte        else        instanceof        return        transient                         
    case        extends        int         short        try 
    catch        final        interface        static         void 
    char        finally         long        strictfp        volatile 
    class        float         native        super while 
    const         for         new switch 
   continue         goto        package        synchronized

4.13命名示例

操作项

命名约定

示例

参数

使用传递值/对象的完整的英文描符。

userID

字段/属性

字段采用完整的英文描述,首字母小写,任何中间单词的首字母大写。

firstName

布尔型方法

用is或has做前缀

isEnough(), hasMoney()

采用完整的英文描述符,所有单词首字母大写

Customer, CustomerCounterTest

源文件

命名同类的定义

Customer.java

部件/组件

使用完整的英文描述来说明组件的用途,将组件类型使用匈牙利命名法则作其前缀。

btnOK, cboTypeList

构造函数

默认的构造函数同类名

Customer()

异常类名

由表示该异常类型等的单词和Exception组成

SQLException, ServiceException

异常实例名

通常采用字母 e 、ex表示异常。 
多个异常时使用异常名或其简写加E、Ex等构成

e, ex, SQLEx

常量

全部采用大写字母,单词之间用下划线分隔。

DEFAULT_NAME

获取成员函数

被访问字段名的前面加上前缀 get。

getUserName()

接口/实现类

使用I前缀/接口实现类命名同接口去掉I的部分,并以Impl做后缀。

IUserService/UserServiceImpl

局部变量

采用完整的英文描述符,第一个字母小写

totalMoney

循环计数器

通常采用字母 i,j,k

i, j, k

采用完整的英文描述符,所有单词都小写,所有包属于com.glodon

com.glodon.gcp.buyer, 
com.glodon.gcp.seller

方法

采用完整的英文描述说明方法功能

第一个单词尽可能采用一个生动的动词,除第一个单词外,每个单词第一个字母大写。

openFile() 
addUser()

5.语句规范

5.1语句总则

  1. 统一使用Eclipse格式化工具进行格式化,默认快捷键:Ctrl+Shift+F
  2. 尽量避免强制类型转换。如果不得不做类型转换,尽量用显式方式。
  3. If else 中的业务代码行数太长,否则就要考虑用函数封装
  4. 避免在表达式中用赋值语句
  5. 避免对浮点类型做等于或不等于判断
  6. 杜绝魔法数字, for循环的最大数等也要用变量代替,以便知道是什么含义
  7. 对象比较运算,常量放在前面,比如"aaa".equals(str)
  8. Boolean的"假"判断格式:if(false==isMax) 而不用if(!isMax),因为非符号"!"不清晰
  9. 如果一段带有业务逻辑的代码超过两次用到,就将其封装成一个方法
  10. 单个循环也要用{}
  11. 每个变量仅有一个唯一的用途
  12. 单个函数执行单个功能并与其命名相符
  13. 消除所有编译器警告
  14. 常数变量声明为final
  15. 每个if-else if-else语句都有最后一个else以确保处理了全集
  16. 对于流操作代码的异常捕获有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
    }

  17. 对同步对象的遍历访问必须进行代码同步处理
  18. 在对Map对象使用迭代遍历过程中保证没有做增减元素操作
  19. If else判断语句避免头重脚轻,比如if的代码段过大,else的代码很短,这时候要调整结构
  20. 每一行最多包含一条语句。

5.2循环语句

  1. 务必检查,杜绝死循环
  2. 即使循环体只有一条语句,也要用花括号括起
  3. 尽量不用空语句,特殊情况用到空语句,写好注释,告诉读者这不是bug

    for (initialization; condition; update){ 
         //已经在条件中执行 
    }

    while (condition){ 
         //暂时什么也不做, 


    注:这样做是为了告诉阅读者,这是正常程序而不是遗漏造成的bug。

  4. 循环中禁止使用访问数据库的操作,循环内部如果需与数据库交互,而应提前一次性读取出。

5.3Switch-case

  1. 语句switch中的每个case各占一行。
  2. 所有的非空 case 语句必须用 break; 语句结束。例:

    switch (score) {                                                                                       
         case 1: 
                str = "good"; 
                break
         case 2: 
               str = "bad"; 
               break
         default
               str = "nothing"; 
               break
    }

  3. 语句switch中的case按字母顺序排列。
  4. 为所有switch语句提供default分支。

6.注释规范

6.1注释总则

  1. 如果你的程序不值得注释,那么它很可能也不值得运行。
  2. 避免使用装饰性内容,保持注释的简洁。
  3. 注释信息不仅要包括代码的功能,还应给出原因,不要为注释而注释。
  4. 除变量定义等较短语句的注释可用行尾注释外,其他注释当避免使用行尾注释。
  5. 注释类型:javadoc注释,失效代码注释(eclipse下ctrl+shift+/),代码细节注释 //。
  6. 对类、方法、变量等的注释需要符合JavaDoc规范,对每个类、方法都应详细说明其功能、条件、参数等,并使用良好的HTML标记格式化注释,以使生成的JavaDoc易阅读和理解。
  7. 如果注释太复杂说明程序需要修改调整,使设计更加合理。
  8. getter、setter方法不用注释
  9. 注释不能嵌套
  10. 生成开发文档的需要用中文编写
  11. 如果需要注释的内容太多,需附加文档进行说明, 注释时加上"参见《****》"
  12. 距离较远的}必须注释
  13. 复杂的分支流程必须注释
  14. 代码质量不高但能正常运行,或者还没有实现的代码用//TODO:声明
  15. 存在错误隐患的代码用//FIXME:声明

6.2文档注释

Javadoc注释可以产生代码的文档。为了可读性,可以有缩进和格式控制。文档注释常采用一些标签进行文档的特定用途描述,用于帮助Javadoc产生文档,常用的有:

标签

应用对象

目的

@author name

类/接口

描述代码的作者,每个作者对应一个这样的标签

@deprecated

类 
成员方法

说明该段API已经被废除

@exception name description 
或 
@throws name description

成员方法

描述方法抛出的异常 
每个异常一个对应一个这样的标签

@param name description

成员方法

描述成员方法中的参数用途和意义,一个参数对应一个这样的标签

@return description

成员方法

描述成员方法的返回值的意义

@since

类/接口 
成员方法

描述该段API开始的时间

@see ClassName

类/接口 
成员方法 
成员变量

用于引用特定的类描述,一般ClassName用包括包名的全名

@see ClassName#memberfunction

类/接口 
成员方法 
成员变量

用于引用特定的类的成员方法的描述,一般ClassName用包括包名的全名

@version text

类/接口

版本

@inheritDoc

类/接口 
成员方法

继承的文档

6.3屏蔽代码

对于临时废弃或为了调试程序而临时屏蔽的代码段,可以注释掉。如:

/** 
public GldBbb(String userName, String company) {                                                
     this.userName = userName; 
     this.company = company; 

*/

6.4类注释

在类、接口定义之前当对其进行注释,一般比较详细,其内容至少要包含:功能说明、@author作者、@version版本, @date创建日期、 (see参照,)since开始版本等几个方面。
为了使形成的文档可读性好,注释中经常带有缩进和格式控制。类描述放在类的类定义的紧前面,不能有任何的空行。
以jdk的Number类为例:

/** 
* The abstract class Number is the superclass of classes 
BigDecimalBigInteger
ByteDoubleFloat
IntegerLong, and Short

 
* Subclasses of Number must provide methods to convert 
* the represented numeric value to bytedouble
floatintlong, and 
short

@authorLee Boynton 
@authorArthur van Hoff 
@version 1.30, 11/17/05 
@see java.lang.Byte 
@see java.lang.Double 
@see java.lang.Float 
@see java.lang.Integer 
@see java.lang.Long 
@see java.lang.Short 
@since JDK1.0 
*/ 
public abstract class Number implements java.io.Serializable {                                                                

6.5函数注释

依据标准JavaDoc规范对方法进行注释,以明确该方法功能、作用、各参数含义以及返回值等。复杂的算法用/**/在方法内注解出。
注释可以很详细,为了可读性强也可包含格式控制,方法注释一般包括:

  1. 方法的主要说明,描述方法完成什么样的功能
  2. @param c elements to be inserted into this list.(参数说明)
  3. @return true if this list changed as a result of the call.(返回值说明)
  4. @throws NullPointerException if the specified Collection is null.(异常说明)
  5. @see如果重载方法必须参考父类的方法
  6. Eclipse下采用Alt+Shift+J生成Javadoc

/** 
* 检查类的变量是否存在 
@param clazz 类名 
@param field 变量名,该名称大小写敏感 
@return 变量名是否存在,true:存在,false:不存在 
*/ 
public static boolean checkField(String clazz,String fieldName){                                                 
     try { 
         Class c = Class.forName(clazz); 
         if(c.getDeclaredField(fieldName)!=null){ 
             return true
         } 
     } catch (Exception e) {

         e.printStackTrace();
     } 
     return false
}

6.6代码注释

例:

//用户名 
String userName = null;

算法设置

算法描述指在实现级别的描述注释,如在方法内的注释,这样使得程序更加易懂,方便程序算法的修改和BUG的修复。一般采用块/行注释,对于简短的描述采用行注释,不要用文档注释。注释的主要内容包括:

  • 某些局部变量的意义和用途
  • 复杂的控制结构的注释,如循环,分枝,条件表达式。说明控制所要达到的目标
  • 复杂的代码段的描述,说明代码完成的功能,以及为什么这样做。
  • 使用@ inheritDoc开始

块注释: /* */

可以用多行,一般用来对程序块、算法实现、类的实现进行说明。为了可读性,可以有缩进和格式控制。一般在行注释不能满足注释需要的时候采用。一般用来作为文件头、复杂算法的说明,方法体内的复杂过程说明等

6.7变量注释

1. 成员变量、类静态变量采用文档注释,对成员变量的注释通常包括:

  • 变量的意义
  • 变量的合法值域

/** XXXXXX */ 
String username = "xyz";                                                                      

2. 局部变量,如算法相关的变量采用块或行注释

String username = "xyz"; //用户姓名                                                         
//用户姓名 
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其他注释

  1. 应对重要的变量加以注释,以说明其含义等。
  2. 应对不易理解的分支条件表达式加注释。不易理解的循环,应说明出口条件。过长的方法实现,应将其语句按实现的功能分段加以概括性说明。
  3. 对于异常处理当注明正常情况及异常情况或者条件,并说明当异常发生时程序当如何处理。

7.编码格式

7.1基本原则

  1. 一个程序文件最好不要超过1000行
  2. 尽可能缩小对象的作用域,这样对象的可见范围和生存期也都会尽可能地小
  3. 一个方法所完成的功能要单一,不同的功能封装为不同的方法.
  4. 尽可能的处理异常或转换异常,不要一味的包装异常
  5. 如果对象在某个特定范围内必须被清理(而不是作为垃圾被回收),请使用带有finally子句的try块,在finally子句中进行清理。
  6. 对成员变量的访问最好通过getter/setter方法,这样能够保证访问的合法性,以及代码调整
  7. 优先选择接口而不是抽象类或具体类。如果某些东西将成为基类,应当优先把它们设计成接口;只有在必须放进方法定义或成员变量时,才把它修改为具体或抽象类。
  8. 在处理可变String的时候要必须使用StringBuffer类,可变范围在5次以内可以使用String
  9. 使用java标准库提供的容器。优先选择ArrayList来处理顺序结构,选择HashSet来处理集合,选择HashMap来处理关联数组,选择linkedList来处理堆栈和队列。当使用前三个的时候,应该把他们向上转型为List、Set和Map,这样就可以在必要的时候以其它方式实现
  10. 如果数组的长度将来可能突破现有定义,就用ArryList。
  11. 尽量使用"private"、"protected"关键字,这样对改动影响最小,必要时再定义为public。
  12. 采用类而不是对象引用静态变量和方法
  13. 使用Boolean必须采用Boolean.TRUE/Boolean.FALSE进行构造
  14. Boolean.valueof(true|false|y|n|Y|N)的形式进行构造
  15. 禁止后台业务层代码使用如下代码,要输出日志,同时进行异常包装抛出。

    try
    //do something
    }catch(Exception e){                                                                                    
         e.printStackTrace(); 
    }

    7.2类编码格式

import顺序

  1.  import包按一下顺序:
  • jdk标准包
  • java扩展包(例如servlet,javamail等)
  • 使用的外部库的包(例如xml parser)
  • 使用的项目的公共包
  • 使用的模块的其他包

     2.  每一类import后面加一个换行。例如:

import java.io.*; 
import java.util.*; 

import javax.servlet.*; 
import javax.mail.*; 

import com.glodon.util.*;                                                                                  
import com.glodon.gjc.*;

     3.  类的结构组织,一般按照如下的顺序:

  • 常量声明
  • 静态变量声明
  • 成员变量声明
  • 构造函数部分
  • Finalize部分
  • 成员方法部分
  • 静态方法部分

          这种顺序是推荐的,在实际开发中可以按照一定的尺度修改,原则是程序更易读。如对方法的排序按照重要性,或按照字母顺序排列或按照方法之间的关系排列。

      4. 每个方法(包括构造与finalize)都是一个段。多个变量声明按照逻辑共同组成一个段,段与段之间以空行分隔。

      5. 类声明时,要指出其访问控制,一般为没有修饰符,public,和private。

      6. 编写通用性的类时,请遵守标准形式。包括定义equals()、hasCode()、toString()、Clone(实现Cloneable接口),并实现Comparable和Serialiable接口

      7. 对于设计期间不需要继承的类,尽量使用final

7.3变量

  1. 对成员变量, 尽量采用private
  2. 每一个变量声明/定义占一行(参数变量除外),如:int a;int b;比int a,b; 更容易读, 更容易查找bug
  3. 局部变量在使用前必须初始化,一般在声明时初始化

变量的声明要放在程序块的开始位置,如:

void myMethod() { 
    int age = 0; // beginning of method block                                                                                 
    if (age > 10) { 
        int flag = 0; // beginning of "if" block 
        // ... 
    } 
}

一种例外情况是在for语句中,定义声明不仅不占一行,还在表达式内部,完全采用Eclips生成,如:
for(int i = 0; i<100; i++)

      4. 数组的申明采用 <数据类型[] + 变量名>方式如:

      5. char[] buffer; 而不是: char buffer[];

7.4方法

  1. 对成员方法,不要轻易的采用public的成员变量。主要的修饰符有public, private, protected, 无
  2. 空方法中方法声明和函数体不能写在一行,并用TODO标出。

推荐:

public void myFun(){                                                                         
    // TODO 
}

禁止:

public void myFun(){ }                                                                      

  1. 方法和方法之间空一行
  2. 方法参数尽量控制在5个以内,参数过多可封装成对象,以提高程序的可读性和可扩展性,参数分隔符后保持一个空格。
  3. 对于设计期间不需要子类来重载的类,尽量使用final
  4. 每个方法尽量代码行数尽量不要超过100行(有效代码行,不包括注释)

7.5书写规范

  1. 避免变量的定义与上一层作用域的变量同名。
  2. 在字符串变量在与字符串常数作比较时,字符串常数放在比较表达式的前面如:

    String str="bbb"; 
    if("aaa".equals(str)){                                                                                 

    }

  3. Return语句中不要用小括号,除非使表达更清晰,如:

    return (list.size() > 0 ? list.get(0) : null);                                                  

  4. return 语句中不要有复杂的逻辑计算
  5. switch语句,需要一个缺省的分支

8.其他

8.1工程规范

  1. 禁用System.out.println()进行调试信息的输出,而采用统一Logger4j作为日志输出工具。要根据情况分debug、info、warn、error等信息。
  2. 要保证调试信息清晰准确,禁止输出"----------------------------"、"---111111111111111--"、"555555555555555"等随意的字符串。
  3. 对所有的错误代码进行全局唯一编号,格式: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

  1. 一个javaBean类必须有一个不带有参数的公用构造器。
  2. 一个javaBean类不应有公共实例变量
  3. 类变量都为private通过getXxx和setXxx

8.4单元测试规范

  1. 关键代码(public方法、对外接口)必须进行单元测试。
  2. 关键代码的单元测试必须95%的覆盖。
  3. 测试包名:在原包后增加.test后缀(参考spring源码)。
  4. 测试类名:比如原类为BusinessServiceImpl,则测试类名为:TestBusinessServiceImpl

8.5技巧经验

  1. 当API会面对不可知的调用者时,方法需要对输入参数进行校验,如不符合则抛出IllegalArgumentException 。
  2. 在数组中的元素(如String [1]),如果不再使用需要设为NULL,避免内存泄漏。因此直接用Collections类而不要使用数组。
  3. 在不需要封闭修改的时候,尽量使用protected 而不是 private,方便子类重载。
  4. 变量,参数和返回值定义尽量基于接口而不是具体实现类,如Map map = new HashMap();
  5. 和金额相关时,使用BigDecimal,而不是float
  6. 重新抛出的异常必须保留原来的异常,即throw new NewException("message", e); 而不能写成throw new NewException("message")。
  7. 异常要么处理,要么抛出,不允许空的catch块。
  8. 重载方法必须使用@Override,可避免父类方法改变时导致重载函数失效。
  9. 不需要关心的warning信息可以用@SuppressWarnings("unused"), @SuppressWarnings("unchecked"), @SuppressWarnings("serial") 注释。
  10. 如果方法返回值类型是集合(List,Map,Set….)或数组,且记录为空的时候,返回空的集合或数组,不要返回Null。

你可能感兴趣的:(开发语言,java)