Java编码规范

1、引言

1.1、编码规范的意义

一个软件的生命周期中,80%的花费在于维护;

几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护;

编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码;

1.2、适用范围

公司包括研发部、项目实施部和技术支持部在内的所有使用Java开发的程序;

其它编程语言如没有公司专门的编码规范,也应该尽量参考此规范中的要求。

2、程序注释的规范

2.1、注释类型

Ø  文档注释类型:/**  */

Ø  C注释类型:/*  */

Ø  单行注释类型://

2.2、文件头注释

示例:

/******************************************************************

 * TradeOperator.java

 * Copyright 2015 by GNNT Company. All Rights Reserved.

 * CreateDate:2015-4-23

 * Author:LiuZhenXing

 * Version:1.0.1

 ******************************************************************/

说明:

Ø  注释第一行为文件名;

Ø  第二行Copyright的时间为文件初始创建的年份;

Ø  CreateDate为文件初始创建的日期;

Ø  Author为文件初始开发工程师的名字全拼,第一个字母大写;

Ø  Version为此文件的版本号,由开发工程师自行命名。由三位组成,从1.0.0开始,确保每次程序发生变更,版本号增加即可;

2.3、文件修改注释

示例:

/**

 * <b>修改记录:</b>

 * <p>

 * <li>

 * 创建申请结束合同传入信息类,并生成传入参数和其中的验证方法。

 *                                         ---- LiuZhenXing 2015-4-23Version:1.0.0

 * </li>

 *

 * <li>

 * 1.因为管理员的状态判断和合同没有任何关系,所以合同里没必要有管理员状态判断的方法。<br/>

 * 所以本方法的管理员状态判断返回警告信息,通知外部自己进行判断。<br/>

 * 2.修改判断状态的执行方法,将方法放到 Trade 中。

 *                                         ---- LiuZhenXing 2015-4-24Version:1.0.1

 * </li>

 * </p>

 *

说明:

Ø  每对<li></li>对中的内容为每次的修改内容;

Ø  在每条修改记录的最后,用四个横线做分割,记录修改工程师的名字和修改日期;

Ø  修改内容按照时间从前到后排序;

Ø  文件修改记录在每个类说明之前,与类说明在同一个注释段中;

2.4、类注释

示例:

* <b>类说明:</b>

 * <p>

 * 本类为申请结束合同时的操作类。可以同时申请结束多个合同,所以需要传入结束合同编号列表。

 * 同时,结束合同可以由买方、卖方发起,也可以由居间商、机构、会员、系统管理员代为发起。

 * 所以在申请时要记录发起人类型,并且记录申请人编号。

 *

 * 其中申请人类型属性包括:0 合同买方、1 后台管理人员。

 * 以后可能会有所变动,比如可能会增加申请人类型等,申请人定义了常量类,以方便以后的变动需要。

 *

 * </p>

 */

说明:

Ø  必须对类的基本功能进行说明;

Ø  说明类中重要属性使用。如示例中对合同申请人类型的说明;

2.5、类属性和常量注释

示例:

/** 默认申请人,如果不设置申请人,则默认使用本申请人代码 */

publicstaticfinal String DEFAULT_APPLYER = "admin";



/** 默认判断是否需要审核,如果不设置,则默认为不需要审核 */

publicstaticfinalbooleanDEFAULT_ISNEEDAUDIT = false;



/** 合同编号集合 */

private List<Long>tradeIDList;



/**

* 是否需要审核<br/>

* true:需要审核 false:不需要审核<br/>

* 默认为 DEFAULT_ISNEEDAUDIT (false)

*/

privatebooleanisNeedAudit = DEFAULT_ISNEEDAUDIT;

说明:

Ø  一般为单行注释,注释较长,或多行注释更清楚时,可用多行注释

2.6、方法注释

示例:

/**

* <b>方法说明:</b>

* <ul>

* 判断申请人是否有申请结束合同的权限

* </ul>

*

* @param tradeList 合同信息列表

* @return ResultVO 判断申请人是否有权限的结果集

*                 结果中的 result:-1:验证失败、0:需要外部验证、1:验证通过

*                 返回信息在 spring_recode.xml 的 recode 中配置

*/

public ResultVO isHaveApplyRight(List<ES_TradePO> tradeList)

说明:

Ø  必须对方法功能进行说明;

Ø  必须对方法传入各个参数的意义进行说明;

Ø  必须对返回信息进行说明;

Ø  必要时需说明方法存在的缺陷等;

2.7、方法内变量注释

示例:

// 按合同编号区分合同 Map 集合:key:合同编号 value:合同对象

Map<Long, ES_TradePO> tradeMap = new HashMap<Long, ES_TradePO>();



// 按合同买方代码区分合同 Map 集合:key:卖方交易商代码 value:合同对象集合

Map<String, List<ES_TradePO>> tradeBfirmMap = new HashMap<String, List<ES_TradePO>>();



/*

 * 本列表为可能被撤销的合同集合。

 * 当合同为刚申请状态时可能被撤销;

 * 当合同为审核拒绝状态时可能被撤销。

 */

List<ES_TradePO> mayBeWithdowTrade = new ArrayList<ES_TradePO>();

说明:

Ø  必须对变量表达的含义进行说明;

Ø  如果是泛型,必须对泛型意义进行说明;

Ø  方法内变量即使使用“文档注释”方式,当鼠标放到变量上也不会出现提示,更不会导出到 doc 文档中,所以这里用“单行注释”或“C注释”类型;

2.8、单行注释类型

Ø  用于较短的方法内变量注释。一般放在变量上一行,单独占用一行;

Ø  用于较短的方法内单行代码说明,一般放在代码上一行,单独占用一行;特殊情况,如 case 时,也可写在变量后边,与代码同行;

2.9、程序块注释

示例:

/*

* 由于后续代码有需求,要通过合同编号获取合同信息,

* 也需要通过卖方交易商代码获取合同信息。如果每次都要遍历合同列表,

* 则会影响程序执行效率,所以以下构建了两个 Map 实例,

* 分别用合同编号和合同的卖方交易商代码作为key来保存合同信息。

* 后续使用时,可直接通过 Map 获取合同信息,无需反复遍历合同集合。

*/

说明:

Ø  用于说明一块代码实现的功能;

2.10、重要代码注释

示例:

/** ==============================验证申请人是否有权限开始======================= */



// =========================================================================

// 如果申请人类型为: 0:合同买方,则直接判断申请人是否为买方。

//

// 如果申请人类型为:1:后台管理员,则调用 TradePO 中的 isNomalManager 方法,判断管理员状态是否正常。

// =========================================================================

中间是被说明的代码实现



/** ==============================验证申请人是否有权限结束======================= */

说明:

Ø  用于对程序中关键性逻辑的代码进行说明;

Ø  规定用双横线括住,使代码更突出显眼;

 

 

 

2.11、程序修改注释

示例:

//-----------------------------------------------------------------------------------------

/*

case ApplyerTypeConstants.MANAGER ://如果申请人类型为后台管人员

    if(!tradePO.isNomalManager(applyer)){//判断管理员状态是否正常

    // 传入申请人类型为后台管理员,但传入的申请人却不是管理员或者管理员不可用

       result.add(-20032, new Object[] { applyer });

       return result;

    }

    break;

*/

//去掉管理员状态是否正常的判断

//因为管理员是否可用与合同无关,所以在判断时如果是管理员申请的不应该把判断放到 TradePO 中。

//而应该在外部进行判断

//                               ---- LiuZhenXing 2015-4-24

//-----------------------------------------------------------------------------------------

说明:

Ø  必须对修改代码原因进行说明。

Ø  记录修改人和修改日期。

Ø  整个注释部分用单横线括住,即区分重要注释也能更明确表示代码修改原因。

Ø  注释说明和前边 // 之间两个空格

2.12、Java代码修改时需要修改的地方

Ø  需要将以前的代码注释掉,并且增加修改说明,说明为什么将以前的逻辑改为当前的逻辑,是谁改的,什么时间改的

Ø  要在类注释上增加修改说明,是谁该的,时间,版本号

Ø  将整体的工程版本升级成新的版本

Ø  判断是否需要调整文档 (不要忘记文档索引中的文档版本也要调整)

Ø  完成新代码的编写

3、命名规范

3.1、项目命名

Ø  项目名称:sysname(系统名称)  + - + modulename(模块名称)+-+projecttype(工程类型*如果模块下有多个工程时使用)。例如timebargin-core-interface。

Ø  项目名称所有字母必须小写。

Ø  增加任何项目需要由产品经理申报。不可擅自增加工程!

3.2、Jsp命名

Ø  全部小写字母,多个单词之间中线“-”分割。(注:因为数据库和 struts 配置文件中都要配置jsp名称,所以用驼峰法则容易错。)

3.3、Package命名

Ø  根路径为 gnnt.项目版本.<sysname>.<modulename>.<projecttype >(可选)。

Ø  路径中,除二层目录项目版本名称外,全部单词为小写。

Ø  项目版本名称如即将开发的MEBS6。

Ø  单个目录名字不宜过长(最好不超过 15 个字符)。

Ø  在开发中所有功能模块以项目为原子级的。所有子目录不允许放到根目录以外。

Ø  根目录由产品经理级别以上员工订立。

Ø  除本文档中设置的子包外,需建立其他子包的需要产品经理级别以上员工建立。

3.3.1、RMI 实现类路径

Ø  RMI 实现类放到根目录的 rmi.impl 路径下

3.4、类命名

类名中的每个单词的首字母均为大写;当有缩写单词时,需要全词大写。类名总体应该是一个名词。具体类名定义规则如下:

3.4.1、接口(Interface)命名

Ø  接口命名为:I + 接口名称。

Ø  RMI 接口名为:I + 接口名称 + RMI。

Ø  DAO 接口名为:I + 接口名称 + DAO。

3.4.2、接口实现类命名

去掉接口前端 I 作为实现类的名字,如果接口有多个实现类,可在实现类后边增加“_达意单词”进行区分。

3.4.3、抽象类(abstract)命名

A + 类名称。

3.4.4、枚举类(enum)命名

E + 类名称。

3.4.5、线程类(thread)命名

类名称 + Thread

3.4.6、自定义异常类(exception)命名

类名称 + Exception。

3.5、常量命名

示例:

publicstaticfinal String DEFAULT_APPLYER = "admin";

publicstaticfinalbooleanDEFAULT_ISNEEDAUDIT = false;

说明:

Ø  常量名为纯大写,多个单词间用下划线“_”分开。

3.6、变量命名

说明:

Ø  首字母小写,后边单词首字母大写。如果出现简写,则整个简写单词大写。

3.7、方法命名

说明:

Ø  首字母小写,后边单词首字母大写。如果出现简写,则整个简写单词大写。

Ø  方法名总体应该是一个动词。

3.8、公用子包功能归类

3.8.1、po 包

说明:

Ø  存放持久化对象(persistent object)类。(即数据库模型通过映射转化成的持久化类 model)

Ø  命名:表名 + PO。

Ø  表名前缀大写,下划线后第一个字母大写。

Ø  例:表 Ln_Order 对应的 PO 类为 LN_OrderPO。

3.8.2、vo 包

说明:

Ø  存放值对象(value object)类。(通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据。)

Ø  命名:功能名 + VO。

3.8.3、bo 包

说明:

Ø  存放业务对象(business object)类。(在vo、po的基础上进行业务逻辑的加工后产生的业务类。)

Ø  命名:功能名 + BO。

3.8.4、dao 包

说明:

Ø  dao(Data Access Object) 是面向对象的数据库访问接口。

Ø  在其 impl 子包中写接口实现类。

3.8.5、thread 包

存放线程类。

3.8.6、exception 包

存放自定义异常类。

3.8.7、util 包

存放工具类。

3.8.8、enums 包

存放系统中的所有枚举类。

3.9、核心子包功能归类

3.9.1、kernel 包

Ø  存放执行核心业务流程。

Ø  本包下可分为transaction和非transaction目录。transaction目录下的业务功能是配置了事务的,非transaction目录没有配置事务。

Ø  在各自 impl 子包中存放实现类。

Ø  本包中的类为主要实现核心逻辑业务功能类,以供外部调用。

3.9.2、sysscheduler 包

存放系统状态控制等系统调度相关类。

3.9.3、rmi 包

存放对外开放的 RMI 服务接口,在其 impl 子包中存放实现类。

3.10、Web服务子包功能归类

3.10.1、action 包

存放 web 访问的相应 Action 类。

3.10.2、service 包

存放 Web 服务调用的数据库访问事务层。

4、编程书写规范

4.1、缩进

Ø  子代码快为父代码快基础上向后移1个 tab 键

Ø  设定一个 tab 键为 4 个字符

4.2、列宽

Java代码的每行列宽不超过 100 。

4.3、类(class)内容顺序规范

Ø  类的编码顺序为:先是属性,然后是构造方法,再然后是业务方法,最后是属性的 get*** 和 set*** 方法。

Ø  当同一个类中有多个方法处理一个对象时,将其放到一起,并按一定的顺序书写;如:在 DAO 中对一个表的增、删、改、查应该放到一起。顺序为:先写添加方法(add***)、然后是修改方法(update***)、然后是查询方法,查询方法先写按主键查询(get***ByID)、然后写删除方法(del***)。

4.4、其它代码书写要求

Ø  所有 java 代码不允许有警告标志。

Ø  不允许以import java.util.*类似的方式导入,而要明确的import具体类。

Ø  不允许import 从本类中未用到的类,造成资源浪费。

Ø  每个 Java 文件建议不超过 2000 行代码,超过了,建议拆分。

Ø  每个 Java 类建议不超过 150 个方法。

Ø  单行字符数不超过 100 个。

Ø  方法建议不超过 7 个参数,超过的建议封装成对象。尤其是对外 RMI 接口,建议全部封装成对象,以方便扩展。

Ø  非必要情况,代码中不要出现 System.exit(); 方法。

Ø  打印日志,建议少用 System.out.print 方法,最后提交时不允许出现 System.out.print。

Ø  switch 块最后一定要有 default。

Ø  try catch 块最后的 Exception 中非特殊情况不能为空。

Ø  if 最大深度为 4,当if 深度超过 4 建议拆分成多个方法执行。

Ø  try catch 最大深度为 3。

Ø  判断变量和值相等要用“abc”.equale(A),格式,不要用 A.equale(”abc”),防止空指针异常。

Ø  不建议类似的代码风格,不具有可读性:

String b = (a==null || a.length<1) ? null : a.substring(1)。

Ø  禁止直接使用类似于-1, 0, 1, and 2这样的魔法数字,可读性为0。将魔法数字定义为常量。

Ø  数据库中的 char 类型列在 java 代码中不要用 char或Character 类型,全部用 String 类型属性对应;数据库中的 number 类型列在 java 中也不要用 float 类型,全部用 double、int、short 类型属性对应。

5、编程逻辑规范

5.1、把常量放到前边

Ø  当执行字符串比较方法(equals)等时,将字符串放到前边,防止空指针异常产生。

例如:

if(variable.equals(‘literal’)){……}

应改为

if(“literal”.equals(variable)){……}

Ø  当使用 > 、< 、== 、!= 等进行数字判断时,先要判断数字是否为空。

例如:

if( num == 5){……} 或 if(5 == num) {……}

当 num 为 null 时都会有空指针异常。

应在比较前判断空

if(num != null  && num == 5){……}

5.2、不要相信 -1

Ø  不要相信 Javadoc 中的 特殊值判断描述。

例如:

字符串的 indexOf 方法,doc 中的描述为:字符在字符串中第一次出现的位置将作为结果被返回,如果字符串不存在,则返回 -1。

if(string.indexOf(character) != -1){……}

但很多场景下,如过不区分大小写的话,jdk升级后可能会返回 -2 呢?

所以以上代码应改为

if(string.indexOf(character) >= 0){……}

5.3、检查null和长度

Ø  不管什么时候,你有一个集合、数组、或其他的对象,在使用时,先要判断对象不为空,防止空指针异常。

例如:

if(array.length > 0) {……}

应该写成

if(array != null && array.length > 0) {……}

5.4、用大括号括住 switch 的每一个 case 块

Ø  为了程序的易读性和正确性,程序清晰非常重要,而每个 case 的代码快用大括号括住,则程序更清晰。

例如:

switch(value) {

case 1 : int j=1;break;

case 2 : int j=2;break;

default : int j=3;

}

应该写成

switch(value) {

case 1 : {

int j=1;

break;

}

case 2 : {

int j=2;

break;

}

default : {

int j=3;

}

}

5.5、判断与业务顺序规范

Ø  当方法中有多个判断和多个业务查询或操作时,要先进行判断,当判断不满足时返回,全部判断完成后再进行业务操作,防止资源浪费。

5.6、判断思想规范

Ø  一般代码逻辑最好是判断否,当否时,直接返回失败,防止复杂逻辑里的判断嵌套过多影响程序易读性。

例如:

/**获取用户信息*/

public UserPO getUser(String userID) {

   UserPO result = null;

if(userID != null) {//如果用户编号不为空

    result = dao.getUser(userID);

    if(result.getStatus() != 1){//如果用户状态不为正常状态

     result = null;

}

}

return result;

}



以上代码最好改写成

public UserPO getUser(String userID) {

    //判断空

if(userID == null) {

    return null;

}

//获取用户信息

UserPO result = dao.getUser(userID);

//判断用户是否为空

If(result == null || result.getStatus() == null || result.getStatus() != 1){

    return null;

}

  return result;

}

6.     添加模版

为使得代码统一化,且书写方便,使用的开发工具(MyEclips)需要引入以下两个模版:

代码模版

Window——>preferences——> Java——>Code Style——>Code Templates,点击 Import . . .——>查找到金网安泰代码模版.xml——>点击 Apply——>勾选上下边的复选框,然后点击 OK。

格式化模版

Window——>preferences——>Java——>Code Style——>Formatter——>Import…——>查找到金网安泰格式化模版.xml——>点击 Apply,然后点击 OK。

log日志快捷键模版

Windows->Preferences->Java->Editor->Import... ——>金网安泰log日志快捷键模版.xml——>点击 Apply,然后点击 OK。

 

参考:北京金网安泰信息技术有限公司 公开 Java编码规范文档

转载于:https://my.oschina.net/happyran/blog/1583871

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值