目录
1 代码规范
1.1 注释规范
1.1.1 页头注释
所有文件头部需要增加对本文件所属以及相应所具备的功能进行描述。<文件头部>必须包括的重要信息,包括:文件名称、文件功能描述、版本信息、公司版权信息。
示例:
/* @RestUtil.java
*功能描述:主要用于提供实现 Rest 功能的工具类,提供给其它应用程序调用,为系统核心代码之一。
*@author Xxx
* esince YYYY -MM- DD
*/
1.1.2 类或接口注释
示例:
/**
*功能描述:此类用于返回一个字符串的子串,子串开始于第1个参数指定的字符,取第2个参数指定的字符串。
*/
/*类名: substring.java
*@author XXx
*@since YYY -MM- DD
*/
publie String substring(int beginIndex) {
return substring(beginlndex,count);
}
1.1.3 方法注释
方法注释,需要明确方法作用。需要检查可以生成相应的 JAVADOC.
示例:
/**
*功能描述:此方法通过增加2个数字型参数,迟回1个新增的整型的数值,主要是用于满是2个数字相加后将结果以整型数值返回。
*@paran numl —第1个数字
*@paran nun2-第2个数字
*@return int —新增的整型值
*@ethrors 抛出算法异常
*@author XXX
*@since YYYY -YY- DD
private int calculate(int num1,int num2)
throws ArithmeticException
1.1.4 块注释
在一段处理算法或者一个完整处理单元前而描述代码功能以及修改记录。
示例:
/*
*块功能描述:调用持久化类,将数据伐存到库
*
*判断是添加,还是修改
*/
boolean ifSucc = false;
if(request.getParameter("YINGLI_ID") == null) {
String GUID = new RandomGUID().toString();
stressTestDatalean.setUSER_ID(Integer.toString(userld));
stressTestDataBean.setSIGY_ISBN((String)vSectAun.get(0));
stressTestDataBean.setSHENHE_JIEGUO("0");
stressTestDataBean.setCUID(GUID);
stressTestDataBean.setCREATE_DATE("getdate()");
stressTestDataBean.setSTATE("A");
ifSuce = StressTestDataD Ю.addStressTestData(db.stressTestlataBean);
}else{
ifSuce = StressTestataDao.mandStressTestata(db.stressTestDataBoan)
}
1.1.5 特定行注释
Single—Line Comments ,在特定一行中添加注释以说明该行特别的注意。
示例:
if(condition){
/*如果满足条件,则而要按以下逻辑进行处理。*/
...
}
1.1.6 单多行注释
使用//在代码中添加单行或者多行注释。常见用于对代码调度修改时进行注释。
示例:
if(foo>1){
//如果满足 foo 大于1,则继续执行下一个操作
}else {
retun false; //如果不满足 foo 大于1,则返回false
}
1.1.7 尾随注释
在每一段代码中添加尾随注释以增加例如条件判断的可读性。
示例:
Here’s an example of a trailing coment in Java code :
if(a =2){
retun TRUE; /*如果 a 为2的条作,则返回值*/
}else{
retun isPrime(a); /*当它满足条件下返回值*/
}
1.2 命名规范
1.2.1 命名约定
1.2.1.1 包名约定
包名必须小写且采用有实际意义的名称,所有的包放在 org.jeecgframework.web.redw包下面。
示例: org.jeecgframework.web.redw.application.ui;
注:禁止出现类似 mypackage 这样的包名。
1.2.1.2 类名约定
类名以大写开头,如: Line,AudioSystem,尽量使用明确的类引入。
示例:
import java.util.List; //NOT : import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
注: import 应该在 package 后面,并技一定的类别进行分组以空行分隔。
示例:
import java.io.I0Exception;
import java.net.URL;
import java.rmi.RmiServer;
import java.rmi.server.Server;
import javax.swing.JPanel;
import javax.swing.event.ActionEvent;
1.2.1.3 变量约定
变量约定详情如下:
--变量名第一个单词用小写,后面的单词首字母大写,必须是具有实际的意义,不能出现 al ,a2这类。
示例: line,audioSystem
--使用范围大的变量应该有一个长的名字,相应的范围小的变量应该使用短一些的命名,如有意义的变量则需要更明确的写出其用途:
示例: point startingPoint,centerPoint;
name loginName;
--私有变量需要以_结尾,可以很容易与本地变量区分。
示例:
class Person{
private String name_;
...
}
--通常变量应该与之类型使用同一单词.
示例:
void setTopic(Topic topic)//道免使用( Topic value)
//避免使用( Topic aTopic)
//道免使用(Topic t)
void connect(Database database)//使用( Database db)
//避免使用( Database oracleDB)
1.2.1.4 常量约定
静态常量以全大写方式。
示例: MAX_ITERATIONS,COLOR_RED
1.2.1.5 方法约定
方法约定详情如下:
--方法名称以小写开头大写单字首字母混合.
示例:
getName().computeTotalWidth()
--操作方法应该使用有意义的表述单词.
示例:
get/set,add/remove,create/destroy,start/stop,insert/delete ,
increment/decrement,old/new,begin/end,first/last,up/down,min/max,
next/previous,open/close,show/hide,suspend/resume,etc,
adduser()/removeuser()
showlcon()/hidelcon()
1.2.1.6 对象约定
对象名一般不要出现在方法中。
示例: line.getLength();//港免使用 line.getLineLength();
1.2.1.7 文件约定
文件约定详情如下:
--JSP 文件名应该以小写开头,大写后面单词首字母。应该书写有意义的命名如:
示例: perform.jsp
--应该写成一般使用名词或者句子:
示例: performl.ogin.jsp
1.2.1.8 缩写约定
缩写约定详情如下:
--缩写也需要遵守方法名称以小写开头大写单字首字母混合。
示例:exportHtmlSource();//避免使用 exportHTMLSource();
openDvdPlayer();//避免使用 openDVDPlayer();
--尽量不使用缩写.
示例:
cmd 替换成 command
com 替换成 compute
pt 替换成 point
cp 替换成 copy
e 替换成 exception
init 替换成 initializel;
computeAverage(); // 避免使用 compAvg();
ActionEvent event; // 避免使用 ActionEvent e;
catch(Exception exception){// 避免使用 catch(Exception e){
1.2.1.9 英文约定
尽量使用英文而非拼音。
示例:
enployee.getName(); //避免使用 yuangong.getMingZi()
1.2.2 关键字约定
1.2.2.1 变量 get/set 约定
变量访问使用 getter / setter
示例:
employee.getName();
employee.setName(name);
matrix.getElement(2,4);
matrix.setElement(2,4,value);
1.2.2.2 初始 initialize 约定
使用 initialize用于构造某些变量或者数据结构,如: initializeFontSet。
示例: printer.initializeFontSet();//避免使用 printer.init()
1.2.2.3 默认 Default 约定
默认接口可以使用前缀 Default.
示例:
class DefaultTableCellRenderer implements TableCellRenderer{
...
...
}
1.2.2.4 布尔is约定
使用is前缀用于布尔类型,如: isSet,isVisible,isFinished,isFound,isOpen
示例:
Setter 方法需要在变量处标明:
void setFound(boolean isFound);
同样可以使用下面方式:
boolean hasLicense();
boolean canEvaluate();
boolean shouldAbort = false;
1.2.2.5 计算 compute 约定
使用compute前缀用于计算类方法,如: computeAverage,computeInverse,以提供给读者明确的方法含义。
示例:
valueSet.conputeAverage();
matrix.computelnverse();
1.2.2.6 查找 find 约定
使用 find 前缀用于涉及查找类方法,
如: findNearestVerTex findShortestPath ,findSmallestElement,以提供给读者明确的方法含义。
示例:
vertex.findNearestVertex();
matrix.findSmallestElement();
node.findShortestPath(Node destinationNode);
1.2.2.7 复数 s 约定
数量或者集合变量应该使用复示例: Collection < Point > points
1.2.2.8 集合 n 约定
使用 n 前缀可用于集合表示,如; nPoints,nLines
示例: nPoints,nLines //避免使用 nunPoints,nunl.ines
1.2.2.9 数量 Num 约定
使用 Num后缀用于表达数量,如: tableNum,cmployeeNum 。
示例: tableNum,employeeNum
1.2.2.10 迭代 i j k 约定
使用 i,j,k 等用于表示迭代变量。
示例:
for(Iterator i = points.iterator():i.hasNext0:){
……
}
for(int i =0: i<nTables : i ++){
……
}
1.2.2.11 异常 Exception 约定
异常类应该使用 Exception 后缀.
示例:
class AccessException extends Exception {
……
}
1.2.2.12 否定、约定不使用否定词。
示例:
bool isError;//避免使用 isNoError
bool isFound ;//避免使用 isNotFound
1.3 SQL命名规范
1.3.1 数据库设计
数据库设计请参照以下项:
--表和字段全部小写,用“_"分隔表名或字段名中多个词
示例1:
表:[公司简称_模块简称_表简称] redw_ hr_org_dept
每个数据库的主表:
示例2:
表:[公司简称_模块简称]
redw_ reviek_main
示例3:
子表名称:[公司简称_模块简称_主表简称_子表简称]
redw_reviek_detail
示例4:
中间表名称:[公司简称_模块简称_主表简称_字段简称]
redw_ reviek_main_post
示例5:
外键:[字段名_id]
creator_id
示例6:[字段名]
order
1.4 语法规范
1.4.1 语法约定
1.4.1.1 接口声明
类于接口的声明应该包含以下部分:
--Class / Interface 描述包括:作者,功能说明,版本,修改发布日期。
--class or interface 声明。
--Class(静态)变量顺序: publie,protected,package(no access modifier), private
--实例变量顺序: public,protected,package(no access modifier), private.
1.4.1.2 方法限定
方法的限定符应该拨照顺序出现:示例: publie statie double square(double a);至使用 static public double square(double a);
1.4.1.3 数组声明
数组声明应当附于类型
示例: int [] a = new int [20]; //避免使用 int a[]= new int[20]
1.4.1.4 变量声明
变量应该在最小作用范用内声明,需要时声明并初始化变量。不要随意扩大其作用范围,减少变量占用的资源。尽量减少度量存在时间,即用即弃。
1.4.1.5 控制条件
控制条件请参照以下项:
--使用临时变量简化控制条件.
示例:
bool isFinished =( elementNo <0) ||(elementNo > maxElement);
bool isRepeatedEntry = elementNo = lastElement;
if(isFinished || isRepeatedEntry){
...
...
}
//NOT:
if((elementNo く0) ||(elemento > maxElement) || elementNo = lastElement){
...
...
}
--Finally 约定:一定写 finallv ,并清理资源占用:一定要注意在使用的资源霭要在异常可能出现的代码断得到释放,如:
卡例:
public void dataAccessCode(){
Connection conn = null;
try{
conn =getConnection0;
...some code that throws SQLException
}catch(SQLException ex){
ex.printStacktrace();
}finally{
DBUtil.eloseConnection(conn);
}
}
class DBUtil{
publie static void closeConnection(Connection conn){
try{
conn.close();
}bcatch(sQLException ex){
logger.error("Cannot close connection");
throw new RuntimeExceptuon(ex);
}
}
}
1.4.1.6 Exceptions 约
不要忽略 exceptions ,一定要对异常进行处理、记录或者输出。不要只捕获最顶层的 exceptions
示例:下面是一个错误例子
try {
...
}catch(Exception ex){
...
}
1.4.1.7 控制约定
不要使用异常作为程序流控制,不要利用异常处理过程中添加程序控制逻辑。
示例:下而是一个错误例子
public void useExceptionsForFloControl(){
try {
while(true){
increaseCount
}
}catch(MaximunCountReachedException ex){
}1
//Continue execution
public void increaseCount() throws MaxinumCountReachedException{
if(count >=5000){
throw new MaxinumCountReachedException();
}
}
2 测试与 Bug 跟踪
2.1 基本原则测
试不通过的代码不得提交到SVN库或者发布。不得隐瞒、忽略、绕绕过任何Bug ,有 Bug不一定是你的错,但有了Bug不作为就是你的不对了。多做测试,测试要完全尽量将各种可能情况都测试通过,尽量将可能的Bug在开发中捕捉并处理掉。测试要保证可再测试性。测试应当对数据库等资源不留或少留痕迹,例如,当测试添加一个用户时在其成功后当及时从数据库中删除该记录,以避免脏数据的产生(由此衍生的一个经验是将添加、获取、删除一起测试)。对关键功能必须测试并通过,对辅助功能及非常简单之功能可不做测试。
2.2 测试驱动开发
测试驱动开发可很好的避免 Bug 的发生,并提升程序的质量,有助于提高个人的编程水平等,因此在开发中当逐步转向有测试驱动的开开发先与测试,再写代码。具体请参考《测试驱动开发》。
2.3 Junit 单元测试
在 Java 应用中,单元测试使用 Junit 及其衍生工具。在 TestCase 的setUp()中初始化应用,在tearDown()中释放资源可由一个基础 TestCase 完成这些任务,其他 TestCase 继承之。
2.4 自动测试与持续集成
测试应当由系统自动完成并向相应人员发送测试报告。由持续集成工具来完成测试的自动化。
2.5 Bug跟踪和缺陷处理
当系统出现 Bug 时当由该 Bug 的负责人(代码负责人)尽快修改之。 Bug 的处理根据其优先级高低和级别高低先后处理。 Bug 级别和优先级别参见《测试手册》。禁止隐瞒 Bug 。
3 性能与安全
3.1 基本原则
性能的提升并不是一蹴而就的,而是由良好的编程积累的,虽然任何良好的习惯和经验所提升的性能都十分有限,甚至微乎其微,但良好的系统性能却是由这些习惯等积累而成,不积细流,无以成江海!
3.2 String 与 StringBugffer
不要使用如下 String 初始化方法: String str = new String("abcdef");这将产生两个对象,应当直接赋值: String str ="abcdef";
在处理可变 String 的时候要尽量使用 StringBuffer 类, StringBuffer 类是构成 String 类的基础。 String 类将 StringBuffer 类封装了起来,(以花费更多时间为代价)为开发人员提供了一个安全的接口。当我们在构造字符串的时候,我们应该用 StringBuffer 来实现大部分的工作,当工作完成后将 StringBuffer 对象再转换为需要的 String 对象。比如:如果有一个字符串必须不断地在其后添加许多字符来完成构造,那么我们应该使用 StringBuffer 对象和她的append()方法。如果我们用 String 对象代替 StringBuffer 对象的话,将会花费许多不必要的创建和释放对象的 CPU 时间。
3.3 集合
避免使用 Vector 和 HashTable 等旧的集合实现,这些实现的存在仅是为了与旧的系统兼容,而且由于这些实现是同步的,故而在大量操作时会带来不必要的性能损失。在新的系统设计中不当出现这些实现,使用 ArrayList 代替 Vector ,使用 HashMap 代替 HashTable 。若却是需要使用同步集合类,当使用如下方式获得同步集合实例: Wap map = Collections.synchronizedap(new HashMapO):由于数组、 ArrayList 与 Vector 之间的性能差异巨大(具体参见《 Java Citball 》),故在能使用数组时不要使用 ArrayList ,尽量避免使用 Vector 。
3.4 对象
避免在循环中频繁构建和释放对象。不再使用的对忽应及时销毁。如无必要,不要序列化对象。
3.5 同步
在不需要同步操作时避免使用同步操作愿如能使用 ArrayList 时不要使用 Vector 。尽量少用同步方法。避免使用太多的 synchronized 美健字。尽量将同步最小化,即将同步作用到最需要的地方,避免大块的同步块或方法等。
3.6 final
将参数或方法声明成 final 可提高程序响应效率,故此:注意绝对不要仅因为性能而将类、方法等声明成 final ,声明成 final 的类、方法一定要确信不再被继承或重载!不需要重新赋值的变量(包括类变量、实例变量、局部变量)声明成 final 所有方法参数声明成 final 私有( private)方法不需要声明成 final 若方法确定不会被继承,则声明成 final
3.7 垃圾收集和资源释放
不要过分依赖JVM的垃圾收集机制,因为你无法预测和知道 J 在什么时候运行 GC 。尽可能早的释放资源,不再使用的资源请立即释放。可能有异常的操作时必须在 try 的 finally 块中释放资源,如数据库逢接、10操作等:
示例:
Connection conn = null;
try{
// do something
}catch(Exception e){
//异常捕捉和处理
e.printStackTrock();
} finallyl{
//列断 ccan 等是者为null
if(null != conn){
conn ,close0;
}
}// end try...catch...finally
4 应用案例
4.1 Java规范文档
Java 规范文档示例如下:
示例:
/*
*@Hellokorld.java
*功能播述:用于输出最经典的语句 Hellolorld
*@author XXx
*@since YYYY -MM- DD
publie class Hellolorld{ //类名大写开头
publie statie void main(String args []){//方法名用小写
System,out.printIn(" Hello World "); //输出语句,将 Hello Vorld 输
}
}
4.2 JSP 规范文档
JSP 规范文档 JSP 规范文档示例如下:
示例:
<%@page language="java" import="java.util.*" pageEncoding="ISo-8859-1"%>
<%
String path = request.getContetPath();
String basePath = request.getScheme)"://"+ request.getServerName()+":"+request.getServerPort()+ path + "/";
%>
<!DOCТYPE HTML.PLBLIC "-//WзC// DТD HTML.4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePaths%>">
<title> My JSP "MyJsp.jsp"starting page </title>
<meta http-equiv ="pragma" content ="no-cache">
<meta http-equiv ="cache-control" content="no-cache">
<meta http-equiv="X-UA-Compatible" content="IE=Edge;IE=11;IE=10;IE=9">
<meta http-equiv ="expires" content="0">
<meta http-equiv ="keyWords" content="keyword1,keyvord2,keyword3">
<meta http-equiv ="description" content="This is my page">
<!--
<link rel ="stylesheet" type ="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page.<br>
</body>
</html>