Fork me on GitHub

JavaEE程序编码规范

JavaEE程序编码规范

 

变量的命名规则

1.1 常量(包含静态的)

一个或多个英文单词的组合,所有字母均大写,单词之间以“_”分隔,如:

public static final String UPDATE_FLAG = T

final double PI = 3.14;

一般情况下常量的public等修饰符不可少。

1.2 类变量(静态变量)及实例变量

一个或多个英文单词的组合,第一个单词的首字母小写,其他单词首字母均大写,其余所有字母均小写。如:

private ProjectSes projectSes;

private static String providerUrl = http://127.0.0.1;

private Logger logger = Logging.getLogger("TestLogger"); 

一般情况下类变量(静态变量)及实例变量public等修饰符不可少。

1.3 局部变量

一个或多个英文单词的组合,一般采用Hungaryn naming法(匈牙利定义法),如下:

以下是基本数据类型的前缀列表

前缀

含义

实例

 ch

 表示char类型

 char chTemp;

 i

 表示int类型

 int iNumber;

 byte

 表示Byte类型

 byte byteGet;

 s

 表示short类型

 short sNumber;

 l

 表示long类型

 long lNumber;

 f

 表示float类型

 float fCount;

 d

 表示double类型

 double dPrise;

 str

 表示String类型

 String strSend;

 b

 表示boolean类型

 Boolean bFlag;

其他数据类型的前缀列表

前缀

含义

实例

col

表示Collection类型

Collection colUser = new ArrayList();

Collection colUser = new Vector();

lst

表示List类型

List lstUser = new ArrayList();

date

表示Date类型

Date dateStart = new Date();

sb

表示StringBuffer类型

StringBuffer sbName= new StringBuffer(1024)

 

除上述情况以外的数据类型,都以obj作为前缀,后面跟一个能说明变量功能或意义单词作为变量,如:

UserVO objUserVO;

1.4 参数

一个或多个英文单词的组合,第一个单词的首字母小写,其他单词首字母均大写,其余所有字母均小写。如:

public void setProjectVO(ProjectVO projectVO) 

public void setUserId(String userId)

建议方法的参数不要超过5个,超过时可以将多个参数合并为一个对象进行传递

1.5 其它

Ø 常用数据类型的变量,采用固定的命名,包括以下几种:

Connection conn;

ResultSet rs;

PreparedStatement pstmt;

Statement stmt;

Ø 数组变量命名与普通变量命名规则一致,如:

int iProjectId[];

public String userName[];

Ø 每个变量的声明单独占一行。不能一个类型同时声明两个变量。如:int i, j; 这样的写法是不允许的。

Ø 不要在代码中出现不使用的变量,如果以后会用到或有其他用途要写上注释说明。

Ø 类名、变量名中含缩写词组:缩写词组全部大写,如:

String strSQL;

public class ProjectDAO{

}

方法的命名规则

Ø 方法命名的基本原则:容易看懂

Ø 一般的方法名采用两个单词动宾结构形式的名称,两个单词之间不要带其它符号,第二个单词的首字母大写,其它的都小写。

如:readBudget(int budgetId)deleteBudget(int budgetId)

Ø 只有一个动词形式的方法名不推荐使用。

Ø 不容易看明白的方法名或有歧义的方法名可采用多单词的形式,每两个单词之间不要带其它符号,从第二个单词开始,每个单词的首字母大写,其它的都小写。

如:readBudgetByProjectId(int projectId)readBudgetByProjectIdAndYear(int projectId,int year)

Ø 方法命名不得采用缩写形式。

类及接口的命名规则

3.1 一般类名

一个或多个英文单词的组合,所有单词的首字母大写,其余所有字母均小写,如:

public class ProjectUser { 

}

3.2 值对象

数据库表的逻辑名+VO,如:

表PUB_DICTIONARY的值对象名为DictionaryVO。

3.3 Action

表名/模块名+Action,如:

字典的Action类名为DictionaryAction。

3.4 MyBatis配置文件

表名/模块名+SQL.xml,如:

字典模块的MyBatis配置文件命名为DictionarySQL.xml。

3.5 DAO

DAO类名为模块名+DAO,如:

字典DAO类名为:DictionaryDAO

3.6 Application Service

Application Service类名为模块名+AppService,如:

字典Application Service类名为:DictionaryAppService

3.7 工具类

工具类的类名为模块名+Util,如:

字典的工具类名为:DictionaryUtil

3.8 门面类

门面类的类名为模块名+Facade,如:

字典的门面类名为:DictionaryFacade

3.9 代理类

代理类的类名为模块名+Man,如:

字典的代理类名为:DictionaryMan

3.10 异常类

异常类的类名为模块名+Exception,如:

字典的异常类名为:DictionaryException

3.11 接口类

接口类的类名为模块名+Interface,如:

字典的接口类名为:DictionaryInterface

3.12 接口实现类

接口实现类的类名为实现名+Imp,如:

字典的接口实现类名为:DictionaryImp

作用域

4.1 类的作用域

Ø 类的作用域保持最小范围。供包外其它类引用的类才添加public作用域修饰符。

4.2 方法的作用域

Ø 只供对象或类内部调用的方法必须使用private作用域修饰符。

Ø 包外不会调用的方法严禁使用public作用域修饰符。

4.3 属性的作用域

Ø 静态常量(类常量)属性可以使用各种作用域修饰符。

Ø 对象属性变量严禁使用public作用域修饰符。

Ø VO对象属性变量必须使用private作用域修饰符。

4.4 局部变量的作用域

Ø 方法内的变量定义应该遵循最小作用域规则。

如:

// iSize只在下面的for循环中使用

int iSize = alItems.size();

for(int i=0;i<iSize;i++){

……………………………….

}

建议写成:

for(int i=0,iSize = alItems.size();i<iSize;i++){

……………………………….

}

Ø 属性是对象的特征,不要把非对象的属性定义为实例变量。

注释的编写规则

所有类及接口文件要写文件头注释(包含版权等),版权中的年度代码书写的开始年度(Copyright (C) 2011),如下:

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

* Copyright (C) 2011 SunLine Information Technology Co.,Ltd

* All Rights Reserved.

* 本软件为SunLine开发研制。未经本公司正式书面同意,其他任何个人、团体不得使用、

* 复制、修改或发布本软件.

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

 

所有类及接口头要写类注释(包含作者、创建日期等),@author@history中要书写中文名,如果注释的内容比较长则需要加“<br>”。如下:

/**

* 技改项目业务代表实现类.实现新增项目,删除项目等方法,<br>

* 提供对表现层的接口.

* @author  张三

* @since   JDK1.4

* @history 2004-10-15 张三 新建

*/

 

类中必要的方法(包括私有方法)要写方法头注释。其中返回值(@return)需要说明含义,包括整型,布尔型,集合等,如对于整形@return 返回1表示成功0表失败对于集合类型要写明集合内元素的类型@return UserVO的集合。如果注释的内容比较长则需要加“<br>”,如下:

/**

* 修改投标人信息

* @param bidderVO 投标人信息

* @throws BidderException 修改异常

* @throws NoPermissionException 没有修改权限

* @return 修改成功返回1 没有修改返回0

*/

public int updateBidder(BidderVO bidderVO) throws BidderException

 

对代码块的注释,注释语句放在代码块之上,用//进行注释,如果注释语句本身超过一行,则用/* */进行注释。

对某一行代码的注释,注释语句放在代码行的后面,用//进行注释。

建议代码块之间空一行。如下:

public void insertProject(ProjectVO projectVO) {

   // 新增项目信息

  iProjectId = Toolkit.getInstance().getNextKey("Project"); // 取项目ID

     logger.debug("Generate Project ID : " + iProjectId);

     Project objProject = projectHome.create(iProjectId);

     objProject.setProjectVO(projectVO);

<空一行>

/*

 从项目VO中取得申请人ID及联系人ID,

 并将申请人ID及联系人ID插入到PUB_ACCESS_CONTROL表 

*/

     projectVO.setProjectId(iProjectId);  

     this.authProject(projectVO); 

}

格式

引入公司指定的格式化配置文件最新版本,使用Eclipse的格式化功能进行代码格式化。

6.1 缩进

设定为个字符。

6.2 每代码行的长度

代码行的长度不超过120个字符。

6.3 大括号

大括号中的“{”与条件在同一行,“}”单独一行,即使大括号中只有一条执行语句也要使用大括号,如:

if (a == b) {

return 0 ;

}

6.4 空行

类文件头注释、package语句、import语句、类头注释、类的属性、方法等之间都空一行。

类的属性与属性之间、方法与方法之间都空一行。

如下:

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

* Copyright (C) 2011 SunLine Information Technology Co.,Ltd

* All Rights Reserved.

* 本软件为SunLine开发研制。未经本公司正式书面同意,其他任何个人、团体不得使用、

* 复制、修改或发布本软件.

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

<空一行>

package com.comtop.app.project.projectinfo.exception;

<空一行>

import com.comtop.util.BaseException;

<空一行>

/**

 * 公共项目管理异常类.

 * @author  张三

 * @since   JDK1.4

 * @history 2005-03-15 张三 新建

 */

public class ProjectException extends BaseException {

private String message;

<空一行>

/**

... ...

 */

public ProjectException(String message) {

        super(message);

        this.message = message;

    }

<空一行>

/**

... ...

*/

    public String getMessage() {

        return message;

}

}

6.5 空格

=”、“+”、“==”等二元操作符两边分别空一格。如:

int i = 1;

“,”的后面空一格。如:

implements Runnable, cloneable

6.6 import部分

import引用要具体到类名,不能用“*”。

import语句书写的顺序为:Java标准类,第三方软件类库,本公司自己的组件类、本工程其他包中的类。这四部分之间分别空一行。所有需要用到的其他包的类都要在import中应用,不要将类似“new java.util.ArrayList()”的语句写在代码中。

6.7 数字

longdoublefloat型变量后的字母“L”、“D”、“F”均大写。16进制的前缀“0X”要大写“X”,数字部分“AàF”要大写。

代码中不要直接使用数字(-101除外),要先对数字进行变量声明。

性能与安全

7.1 静态检查插件

tptp-analysisPMDfindbugscheckStylecommontools5个插件做为代码自检的标准工具。按照给定的最新版插件配置文件检查,识别问题原因及改进范围,在上传配置库前改进代码格式及性能。

7.2 空指针引用(null pointer dereference)

在使用或引用对象前,要先对其进行检查,判断其是否为空。

7.3 数组引用问题(RETURN ARRAY

不要直接返回指向包含敏感数据的内部数组的引用。不要传回一个数组,而是数组的拷贝。

7.4 硬编码敏感数据(Hard-coded sense data)

应该将敏感数据保存在属性文件中,无论什么时候需要这些数据,都可以从该文件读取。如果数据极其敏感,那么在访问属性文件时,应用程序应该使用一些加密/解密技术,避免导致敏感数据泄露。

7.5 整数溢出

应该对所有整数计算的结果进行检查,防止整数溢出。

7.6 对象初始化

对变量的使用不要依赖于初始化。在使用对象之前,应该检查对象的初始化过程。可以采用如下方法实现:

在每个类中都应该有一个在构造器中设置的私有布尔标志,在每个非 static 方法中,代码在任何进一步执行之前都应该检查该标志的值。如果该标志的值为 true ,那么控制应该进一步继续;否则,控制应该抛出一个例外并停止执行。

7.7 集合对象初始化容量

在初始化StringBuffer、集合类(ListSetMap)等时,一般要指定对象的初始化容量,避免不必要的空间浪费,提升性能。

StringBuffer的初始化容量比PMD插件检查后给出的建议值大一些的值;

ListSet初始化容量可设置为估计值;

Map初始化容量可设置为估计值的2倍到3倍。

7.8 简单参数

方法调用时,传入的参数应该是一个具体对象,而不是一个嵌套另一个方法。比如类似“this.a(b(c()))”,要将方法的返回值赋给变量再作为参数传递。

7.9 Final类和方法

应该将不允许扩展的类和方法应该声明为 final,这样可以防止系统外的代码扩展类并修改类的行为。

避免使用非final的公共静态变量。

7.10 无用的代码

应该将(除启动应用程序的 main() 方法之外的) main() 方法、未使用的方法以及死代码从应用程序代码中除去。

调试使用的控制台输出语句(System.out.println)在调试结束后要删除。

7.11 日志级别

使用正确的日志级别输出,注意infowarningdebugerror等级别的使用场合。禁止使用debug级别输出错误信息,禁止使用errror级别输出调试信息。

7.12 序列化问题

在包含系统资源的直接句柄和相对地址空间信息的字段前应该使用transient关键字。如果资源,如文件句柄,不被声明为transient,该对象在序列化状态下可能会被修改,从而使得被反序列化后获取对资源的不当访问。

为了确保反序列化对象不包含违反一些不变量集合的状态,类应该定义自己的反序列化方法并使用ObjectInputValidation接口验证这些变量。

为了保护虚拟机外的字节流,可以对序列化包产生的流进行加密。字节流加密防止解码或读取被序列化的对象的私有状态。如果决定加密,应该管理好密钥,密钥的存放地点以及将密钥交付给反序列化程序的方式等。

如果一个类定义了自己的序列化方法,它就不能向任何DataInput/DataOuput方法传递内部数组。所有的DataInput/DataOuput方法都能被重写。注意默认序列化不会向DataInput/DataOuput字节数组方法暴露私有字节数组字段。

7.13 通过名称比较类 

在那些非得根据名称来比较类的情况下,必须确保使用了当前类的 ClassLoader 的当前名称空间,如下面示例中所示的一种更好的比较方法:

    if(obj.getClass()== this.getClassLoader().loadClass("com.bar.Vnet")){

        // object's class is equal to

        //the class that this class calls "com.bar.Vnet"

    }else{

        // object's class is not equal to the class that

        // this class calls "com.bar.Vnet"

    }

比较类的更好方法是直接比较类对象看它们是否相等:  

    if(a.getClass() == b.getClass()){

        // objects have the same class

    }else{

        // objects have different classes

    }

应该尽可能少用直接名称比较。

7.14 类克隆

除非有明确的需求,否则要保证你定义的类是不可克隆的。要使类不可被复制,只要在每个类里定义如下方法: 

public final Object clone()

throws java.lang.CloneNotSupportedException{

throw new java.lang.CloneNotSupportedException();

}

如果想让您的类可克隆并且您已经考虑了这一选择的后果,请在你的类中定义一个为 final 的克隆方法

public final Object clone()

super.clone();

}

7.15 JDBC使用

SQL语句变量使用“?”绑定变量。在DAO中,所有SQL语句中的变量都要使用“?”来绑定变量,禁止直接拼凑变量到SQL语句中;

查询分页数据方法中,避免取所有记录的方式。在DAO中,查询分页数据的方法,不得使用取所有记录出来后再分页的方式,而要使用分页SQL语句包装方法。

SQL语句不得在DAO外书写。不得在DAO类外写好SQL语句后传入DAO执行。

查询数据集合时要使用DAO方式,避免使用EntityBean查询数据集合。

7.16 SQL语句

类中包含的SQL语句必须全部大写(包括关键字、表名、字段名等),如:

SELECT PROJECT_NAME FROM IMP_PROJECT WHERE PROJECT_ID = 1

EJBEJB-QL中关键字(WHERE)必须全部大写实体类的别名为英文单词(组合)且单词首字母大写,其余字母全部小写。如:

SELECT OBJECT(User) FROM User AS User WHERE User.Id= ?1

7.17 数据库连接释放

数据库访问可使用EJBEntityBean等,对数据集的访问必须使用DAO方式。

不管代码是否失败,均关闭对数据库的连接。DAO层可使用iBatic等开源框架,如果是手工写SQL语句访问,必须在try语句的finilly块中安全释放数据库连接。

7.18 使用存储过程

对于复杂的数据库操作应该使用存储过程。

存储过程具有更短运行时间和更短的事务锁,具有更高的运行效率。

7.19 第三方组件

慎重使用第三方组件。

如果必须使用第三方组件,那必须遵守以下原则:

1、向你要重用的提供商询问,是否用过findbugs或者类似的工具检查组件,确保供应商进行过足够的安全测试。

2、在你购买之前要求一个findbugs的报告,这可能增加对组件的信任

3、可以对使用的第三方组件进行独立的安全测试。

 

附件





posted @ 2015-08-30 19:52  Dantefung  阅读(522)  评论(0编辑  收藏  举报