疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

最完整的Java编码规范文档


 

 
Java编码规范,好习惯都是日常养成的,别指望看一遍文档就能养成习惯,下边的规范都是世界通用的,只要你是java开发进哪家公司这些规范都是最基本的要求。
 
从第一个Hello Word程序开始就要遵循正确的规范,相信我你会受益终身的。
 
文档偏多,不着急看完,收藏下慢慢看。没事翻一翻,薪资翻倍靠的就是这随手的一翻。
 
1.Java编程规则
 
1.1.包名全都是小写字母
 
Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此。
 
为了保障每个Java包命名的唯一性,在最新的Java编程规范中,要求开发人员在自己定义的包的名称之前加上唯一的前缀。由于互联网上的域名称是不会重复的,所以一般采用自己在互联网上的域名称作为自己程序包的唯一前缀。
 
1.2.类名首字母应该大写、大写中间单词的首字母
 
类的命名
 
类的名字必须由大写字母开头而单词中的其他字母均为小写,例如Circle;如果类名称由多个单词组成,则每个单词的首字母均应为大写例如TestPage;如果类名称中包含单词缩写,则这个所写词的每个字母均应大写,如XMLExample,还有一点命名技巧就是由于类是设计用来代表对象的,所以在命名类时应尽量选择名词。
 
方法的命名
 
方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头,如sendMessge。
 
变量的命名
 
变量的命名规范和方法的命名规范相同。
 
常量的命名
 
常量的名字应该都使用大写字母,并且指出该常量完整含义。如果一个常量名称由多个单词组成,则应该用下划线来分割这些单词,如MAX_VALUE。
 
参数的命名
 
参数的命名规范和变量的命名规范相同,而且为了避免阅读程序时造成迷惑,请在尽量保证参数名称为一个单词的情况下使参数的命名尽可能明确。
 
1.3.大写static final基本类型标识符中的所有字母
 
若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。
 
1.4.考虑置入一个main()
 
对于自己创建的每一个类,都考虑置入一个main(),其中包含了用于测试那个类的代码。为使用一个项目中的类,我们没必要删除测试代码。若进行了任何形式的改动,可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。
 
1.5.应将方法设计成简要的、功能性单元
 
用它描述和实现一个不连续的类接口部分。理想情况下,方法应简明扼要。若长度很大,可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用(有些时候,方法必须非常大,但它们仍应只做同样的一件事情)。
 
1.6.使类尽可能短小精悍
 
使类尽可能短小精悍,而且只解决一个特定的问题。下面是对类设计的一些建议:
 
一个复杂的开关语句:考虑采用“多形”机制
 
数量众多的方法涉及到类型差别极大的操作:考虑用几个类来分别实现
 
许多成员变量在特征上有很大的差别:考虑使用几个类
 
1.7.让一切东西都尽可能地“私有”— private
 
让一切东西都尽可能地“私有”——private。可使库的某一部分“公共化”(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。若只公布自己必须公布的,就可放心大胆地改变其他任何东西。在多线程环境中,隐私是特别重要的一个因素——只有private字段才能在非同步使用的情况下受到保护。
 
1.8.对象表达的应该是应用程序的概念,而非应用程序本身。
 
谨惕“巨大对象综合症”。对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。
 
1.9.考虑是否采用内部类
 
任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作。
 
1.10. 尽可能细致地加上注释
 
尽可能细致地加上注释,并用javadoc注释文档语法生成自己的程序文档。
 
规格如下:
 
/**
 
* 方法说明:资金存取总额异常
 
* @param ci ComInput 输入参数含义 备注信息
 
* @throws Exception
 
* @return ComOutput 返回结果含义 备注信息
 
*/
 
public ComOutput auFundAccessTotal(ComInput ci ) throws Exception{
 
}
 
1.11. 抛出构建器内的异常
 
涉及构建器和异常的时候,通常抛出在构建器中捕获的任何异常——如果它造成了那个对象的创建失败。这样一来,调用者就不会以为那个对象已正确地创建,从而盲目地继续。
 
1.12. 进行必要的对象清除
 
当客户程序员用完对象以后,若你的类要求进行任何清除工作,可考虑将清除代码置于一个良好定义的方法里,采用类似于cleanup()这样的名字,明确表明自己的用途。除此以外,可在类内放置一个boolean(布尔)标记,指出对象是否已被清除。在类的finalize()方法里,请确定对象已被清除,并已丢弃了从RuntimeException继承的一个类(如果还没有的话),从而指出一个编程错误。在采取象这样的方案之前,请确定finalize()能够在自己的系统中工作(可能需要调用System.runFinalizersOnExit(true),从而确保这一行为)。
 
在一个特定的作用域内,若一个对象必须清除(非由垃圾收集机制处理),请采用下述方法:初始化对象;若成功,则立即进入一个含有finally从句的try块,开始清除工作。
 
若在初始化过程中需要覆盖(取消)finalize(),请记住调用super.finalize()(若Object属于我们的直接超类,则无此必要)。在对finalize()进行覆盖的过程中,对super.finalize()的调用应属于最后一个行动,而不应是第一个行动,这样可确保在需要基础类组件的时候它们依然有效。
 
1.13. 创建大小固定的对象集合时,请将它们传输至一个数组
 
创建大小固定的对象集合时,请将它们传输至一个数组(若准备从一个方法里返回这个集合,更应如此操作)。这样一来,我们就可享受到数组在编译期进行类型检查的好处。此外,为使用它们,数组的接收者也许并不需要将对象“造型”到数组里。
 
1.14. 尽量使用interfaces,不要使用abstract类
 
尽量使用interfaces,不要使用abstract类。若已知某样东西准备成为一个基础类,那么第一个选择应是将其变成一个interface(接口)。只有在不得不使用方法定义或者成员变量的时候,才需要将其变成一个abstract(抽象)类。接口主要描述了客户希望做什么事情,而一个类则致力于(或允许)具体的实施细节。
 
1.15. 在构建器内,只进行那些将对象设为正确状态所需的工作
 
在构建器内部,只进行那些将对象设为正确状态所需的工作。尽可能地避免调用其他方法,因为那些方法可能被其他人覆盖或取消,从而在构建过程中产生不可预知的结果。
 
1.16. 尽量新建类,避免继承
 
在现成类的基础上创建新类时,请首先选择“新建”或“创作”。只有自己的设计要求必须继承时,才应考虑这方面的问题。若在本来允许新建的场合使用了继承,则整个设计会变得没有必要地复杂。
 
1.17. 保证在自己类路径指到的任何地方,每个名字都仅对应一个类
 
为避免编程时遇到麻烦,请保证在自己类路径指到的任何地方,每个名字都仅对应一个类。否则,编译器可能先找到同名的另一个类,并报告出错消息。若怀疑自己碰到了类路径问题,请试试在类路径的每一个起点,搜索一下同名的.class文件。
 
用合理的设计方案消除“伪功能”。也就是说,假若只需要创建类的一个对象,就不要提前限制自己使用应用程序,并加上一条“只生成其中一个”注释。请考虑将其封装成一个“独生子”的形式。若在主程序里有大量散乱的代码,用于创建自己的对象,请考虑采纳一种创造性的方案,将些代码封装起来。
 
1.18. 避免使用“魔术数字”
 
避免使用“魔术数字”,这些数字很难与代码很好地配合。如以后需要修改它,无疑会
 
成为一场噩梦,因为根本不知道“100”到底是指“数组大小”还是“其他全然不同的东西”
 
。所以,我们应创建一个常数,并为其使用具有说服力的描述性名称,并在整个程序中都采用常数标识符。这样可使程序更易理解以及更易维护。
 
1.19. 警惕“分析瘫痪”
 
请记住,无论如何都要提前了解整个项目的状况,再去考察其中的细节。由于把握了全局,可快速认识自己未知的一些因素,防止在考察细节的时候陷入“死逻辑”中。
 
1.20. 警惕“过早优化”
 
首先让它运行起来,再考虑变得更快——但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候,才应进行优化。除非用专门的工具分析瓶颈,否则很有可能是在浪费自己的时间。性能提升的隐含代价是自己的代码变得难于理解,而且难于维护。
 
1.21. 谨惕“巨大对象综合症”
 
对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。
 
2.Java编程规范
 
根据第一部分的Java编程规则,来制定本命名规范。请参考附件一Sample.java文件
 
包的命名
 
全都小写,即便中间的单词亦是如此,并且以com.shinetecnology.为开始部分,接下的字段用来表示项目名称,再下个字段用来表示此项目里的某个模块。
 
如com.shinetechnology.ecrm.namesample
 
请在每个类文件里填写包名,使类易于管理。
 
2.1.类的命名
 
类名通常用有意义的名词或名词短语来表示,首字母大写,并大写中间单词的首字母。如:Class NameSample{}
 
2.2.常用类型变量的命名
 
常用类型变量名一般用有意义的名词或名词短语来表示,请不要用下划线。如果只有一个单词,则全部小写,如果有多个单词,则头一个单词小写,其余单词的首字母大写。如int pageNum。
 
要避免用单个字母来对变量进行命名,除了临时变量和循环变量。
 
对临时变量和循环变量的命名一般来说:
 
• by for a byte
 
• c for a char
 
• d for a double
 
• e for an Exception object
 
• f for a float
 
• g for a Graphics object
 
• i, j, k, m, n for integers
 
• p, q, r, s for String, StringBuffer, or char[] objects
 
• b for a boolean
 
• str for String
 
• sh for short
 
2.3.常量的命名
 
常量一般用有意义的单词或字母来命名,可用下划线,并全部大写。
 
如: final double PI=3.1415926
 
2.4.数组变量的命名
 
数组变量名一般用有意义的名词或名词短语来表示,请不要用下划线。如果只有一个单词,则全部小写,如果有多个单词,则头一个单词小写,其余单词的首字母大写。如int [] pageNum
 
2.5.对象变量的命名
 
一般说来,用该对象所属类型名称来命名,并把第一个字母小写;
 
如 Sample sample=new Sample()或者用有意义的单词放在类型名称前面,来命名;如 Element pageNumElement= new Element();
 
2.6.函数的命名
 
函数的命名与变量的命名类似,一般用表示目的的动词或动词短语来表示,如果只有一个单词,则全部小写,如果有多个单词,则头一个单词小写,其余单词的首字母大写。
 
如 public void printString(String tmpStr){}
 
2.7.函数的描述
 
请在函数的定义前用/** */来包含函数描述。
 
 
/**
 
* 方法说明:取部门用户信息
 
* @param comInput 统一入口
 
* @throws Exception
 
* @return comOutput 返回统一出口,具体参数如下:
 
* @return retCode:0正常;-1其他原因
 
* @author XXX
 
* @seeXXX 2006-03-22 创建
 
* @seeXXX 2006-03-24 修改
 
*/
 
public ComOutput getAllUserInfo() throws Exception{
 
其中“打印字符串”表示的是这个函数的功能,@param表示这个函数的参数列表,@return表示这个函数的返回值,@throws表示这个函数会抛出什么异常,@author表示这个函数的作者
 
附件一:Sample.java
 
/*
 
*包的命名
 
*/
 
package com.shinetechnology.ecrm.namesample;
 
/**
 
<br>Title: 命名例子
 
<br>Description: 与文档一起,来说明命名规则的例子
 
<br>Copyright: Copyright (c) 2003
 
<br>Company: ShineTechnology
 
@author linsogin
 
@version 1.0
 
*
 
*/
 
public class Sample {
 
/**
 
*常用类型变量的命名
 
*/
 
String companyName;
 
/**
 
*常量的命名
 
*/
 
final String PI="3.1415926";
 
/**
 
*数组变量的命名
 
*/
 
String [] companyNames;
 
/**
 
这个main函数一般用来演示如何使用此类
 
@param args
 
*/
 
public static void main(String[] args) {
 
/*
 
*对象变量的命名
 
*/
 
Sample sample = new Sample();
 
sample.printString("打印出来了!");
 
}
 
/**
 
* 方法说明:取部门用户信息
 
* @param comInput 统一入口
 
* @throws Exception
 
* @return comOutput 返回统一出口,具体参数如下:
 
* @return retCode:0正常;-1其他原因
 
* @authorXXX
 
* @seeXXX 2006-03-22 创建
 
* @seeXXX 2006-03-24 修改
 
*/
 
public ComOutput getAllUserInfo() throws Exception{
 
……
 
 
}
 
2.8.代码注释
 
尽可能细致地加上注释,并用javadoc注释文档语法生成自己的程序文档。
 
规格如下:
 
/**
 
* 方法说明:资金存取总额异常
 
* @param ci ComInput 输入参数含义 备注信息
 
* @throws Exception
 
* @return ComOutput 返回结果含义 备注信息
 
*/
 
public ComOutput auFundAccessTotal(ComInput ci ) throws Exception{
 
}
 
2.9.代码排版
 
代码缩进风格;
 
在我们系统的ejb开发中特别对SQL语句的缩进有严格的要求;
 
2.10. 书写规范
 
书写规范即在编写代码过程中所使用的标准格式, 主要包括空格的使用、括号的使用、缩进格式和其他一些内容。
 
1) 关于空格
 
1、在类型强制转化操作符与操作对象间不应有空格,
 
错误:y = (double) x + 16.7; 正确:y = (double)x + 16.7;
 
2、在条件语句标识符if与其后的括号间应有一个空格,
 
错误: if(x < y); 正确: if (x < y);
 
3、在条件语句中,表达式与括号间不应有空格,
 
错误: if ( x < y ); 正确: if (x < y);
 
4、方法名与括号间以及方法的参数与括号间都不应有空格;
 
错误: return ( x + y ); 正确: return(x + y);
 
5、赋值运算符前后应各有一个空格,包括=, +=, -=, *=, /=, %=, >>=, <<=, &=, 和 ^=。
 
6、条件运算符前后应各有一个空格,包括?和:
 
7、关系运算符前后应各有一个空格,包括<, <=, >, >=, ==, 和 !=;
 
8、逻辑运算符前后应各有一个空格,包括&& 和 ||;
 
9、位运算符前后应各有一个空格,包括&, ^, |, <<, 和 >>;
 
10、算术运算符前后应各有一个空格,包括*, /, %, +, and -,不包括++和--;
 
注:若操作符前后由括号,参照规则13;
 
11、逗号和分号后应有空格;
 
12、一元运算符与操作数间不应有空格, - (negation
 
), + (value of operand), ++, --, !,
 
13、在一级运算符前后不应有空格,包括(), [], ., 和 ->;
 
注:条件判断语句参照规则2、3;
 
14、在局部变量声明和代码间应至少有一个空行;
 
2) 括号的使用
 
原则:应尽量使用圆括号分隔表达式中的各部分,增强可读性;
 
1、 条件语句中各逻辑部分应以圆括号分隔,即使不是必须的;
 
错误: if (a == b && c == d)
 
正确: if ((a == b)&&(c == d));
 
2、 花括号,前一个花括号应在相应的控制语句的后面,前面一个空格;后一花括号应独自占一行;
 
正确: if (x < y) {
 
x = y;
 
}
 
错误: if ( x < y)
 
{
 
x = y;
 
}
 
3、 条件分支的语句即使只有一行或0行,仍应使用{};
 
错误: if (x < y)
 
printf(“%d”, x);
 
正确: if (x < y) {
 
printf(“%d”, x);
 
}
 
3) 缩进
 
1、 花括号对中后一个花括号,与相应的控制语句同列;
 
错误: for (i = 0; i < 10; i++)
 
{
 
}
 
错误: for (i = 0; i < 10; i++){
 
}
 
正确: for (i = 0; i < 10; i++) {
 
}
 
2、 所有花括号中的程序体(包括局部变量定义等)都应在花括号的基础上缩
 
进一个TAB的距离,注意不要使用空格缩进;
 
3、 在switch-case结构中,case语句距离switch 语句的开始应缩进一个TAB,每个case的程序体距离case的开始缩进一个TAB;
 
举例:
 
switch (value) {
 
case 1:
 
/* Body for case 1. */
 
break;
 
case 2:
 
/* Body for case 2. */
 
break;
 
default:
 
/* Body for default. */
 
break;
 
}
 
4、 同一层次的条件语句应处在相同的列。
 
Example (错误 Usage):
 
if (condition1 == TRUE) {
 
/* Body of if. */
 
}
 
else
 
if {
 
/* Body of second if. */
 
}
 
else {
 
/* Body of else. */
 
}
 
Example (正确 Usage):
 
if (condition1 == true) {
 
/* Body of if. */
 
} else if {
 
/* Body of second else if. */
 
} else {
 
/* Body of else. */
 
}
 
5、在try 与 catch、finally 对,if 与 else 对中,catch、else 与上一个花括号同一行。catch、finally 、else前后都应有一个空格.
 
例:
 
try {
 
/*try 语句块*/
 
} catch (Exception e) {
 
/*catch 语名块 */
 
} finally {
 
/*finally 语句块 */
 
}
 
5) 其他
 
1、 对复杂的条件语句(分支中的语句较多),应在每个结束的花括号后加一条注释说明是
 
哪一个分支的结束,并在分支的开始加注释说明进入分支的条件;复杂的循环程序段遵循此规则;
 
2、 每个语句占一行;
 
3、方法定义时,方法的返值和方法名应在同一行;
 
4、方法的参数
 
使用有意义的参数命名,如果可能的话,使用和要赋值的字段一样的名字:
 
SetCounter(int size) {
 
this.size = size;
 
}
 
5、数组应该总是用下面的方式来命名:
 
byte buffer[];
 
而不是:
 
byte[] buffer;
 
2.11. 2.11. Import 语句
 
Import 语句必须详细的写清楚具体的类,尽量避免使用 .* 语句。
 
正确的规则如下:
 
import java.util.ArrayList;
 
import java.util.Hashtable;
 
import org.apache.foo.Bar;
 
import org.apache.bar.Foo;
 
避免使用:
 
import java.util.*;
 
import org.apache.foo.*;
 
import org.apache.bar.*;
 
3.J2EE命名规范
 
3.1.J2EE应用程序和模块的命名
 
3.1.1. 应用程序的命名
 
应用程序的名字被应用于程序文件打包后的存档文件(archive)的文件名。文件名应该是全部小写的ASCII码字符且体现系统的含义。为避免名字的冲突, 文件名可以用更详细和精确的文字命名。
 
格式:
 
Application archive: <application-name> .ear
 
用例:
 
petstore.ear
 
或者更详细
 
bppetstore.ear
 
应用程序显示的名字(出现在应用程序的发布文件中)是大小写混合的被扩展的应用程序名。
 
格式:
 
expanded-application-name>EAR
 
用例:
 
<display-name>PetStoreEAR</display-name>
 
或者更详细
 
<display-name>BluePrintsPetStoreEAR</display-name>
 
3.1.3. Web模块的命名
 
Web模块的名字被用作Web存档文件的文件名。模块的命名应基于所在的JAVA包的名字且全部小写的ASCII码字符。为避免名字的冲突, 文件名可以用更详细和精确的文字命名.
 
格式:
 
Web archive: <module-name>.war
 
Applet client archive: <module-name>-applet-client.jar
 
Midlet client archive: <module-name>
 
Application client archive: <module-name>-app-client.jar
 
用例:
 
com.sun.j2ee.blueprints.petstore
 
petstore.war // Web archive
 
petstore-applet-client.jar // Applet archive
 
或者更详细:
 
bppetstore.war // Web archive
 
bppetstore-applet-client.jar // Applet archive
 
Web模块显示的名字(出现在应用程序的发布文件中)是大小写混合的被扩展的模块名。
 
格式:
 
<expanded-module-name>WAR
 
用例:
 
<display-name>PetStoreWAR</display-name>
 
或者更详细:
 
<display-name>BluePrintsPetStoreWAR</display-name>
 
3.3.Web组件的命名
 
3.4.Servlet
 
格式:
 
实现的类: <component-name> Servlet
 
Web发布文件的名字: component-name
 
Web发布文件显示的名字: <expanded-component-name>Servlet
 
3.5.JSP
 
JSP的文件名必须由大写字母开头而单词中的其他字母均为小写。可以以多个单词组成,其中包含的所有单词都应紧靠在一起,而且每个单词的首字母必须小写。
 
用例:
 
PerformLogin.jsp
 
3.6SQL语句编写注意点
 
特别对SQL长语句字符串相加尽量用StringBuffer.append(…),提高效率;