java程序编码规范


0.写在开始之前

本文翻译自Sun的《Code Conventions for the JavaTM Programming Language》,章节号和原文对应,并且删除了一些我认为不必要的章节片段,当然,这种删除就包含了我个人的倾向,另外,有一句用蓝色标注出来,那是我个人添加的。

如果读者认为阅读一篇14页的文档实在太累了,那么可以直接跳到第12节,这一节在原文中并不存在,是我加上去的。

3.文件组织

程序文件由一些片段组成,这些片段由空白行和注释分隔开。

3.1 java源文件

每个java源文件仅包含一个公共类或接口。

4.缩进

应该以4个空格为一个缩进单位。

4.1行长

一行不应多于80个字符。

4.2折行

当一个表达式不能书写在一行之内时,应该依据下面的原则断开它:

· 在逗号后断开

· 在操作符之前断开

· 高层级断开优先于低层级断开

· 后面的行和前面的行左对齐

· 假如上面的那些规则不好使,那你就缩进8个空格吧。

下面是一些例子:

someMethod(longExpression1, longExpression2, longExpression3,

longExpression4, longExpression5);


var = someMethod1(longExpression1,

someMethod2(longExpression2,

longExpression3));

下面是断开算数表达式的两个例子。第一个例子是被推荐的,因为它在括号之外断开,那是一个较高的层级。

longName1 = longName2 * (longName3 + longName4 - longName5)

+ 4 * longname6; // PREFER


longName1 = longName2 * (longName3 + longName4

- longName5) + 4 * longname6; // AVOID

下面的这个例子中,第二和第三行都缩进了8个空格,而不是把第三行缩进16个空格,那样将使第三行太靠右。

//INDENT 8 SPACES TO AVOID VERY DEEP INDENTS

private static synchronized horkingLongMethodName(int anArg,

Object anotherArg, String yetAnotherArg,

Object andStillAnother) {

...

}

使用8个空格进行折行缩进的目的是使程序看上去更清晰。


5.注释

java程序有两种注释:实现注释和文档注释。实现注释的定界符是 /*...*/ 和 //。文档注释是java仅有的,定界符是 /**...*/,用于产生javadoc。

注释应该仅与阅读和理解程序有关,像如何编译包这样的信息不应包含在注释中。

注意:有时,注释出现的频率反映了代码的质量。当你感觉要被迫加上注释时,考虑重写一下代码,以使它变得清晰。

不要写类似于下面这样格式的注释。

{*******************************************************}

{ }

{ One Test Visual Net Library }

{ }

{ Copyright (c) 1995,98 some Corporation }

{ }

{*******************************************************}

5.1“实现注释”格式

程序可以有四种“实现注释”的格式:块、单行、尾部、行末。

5.1.1块注释

块注释用于提供文件、方法、数据结构和语法的描述。块注释可能出现在文件开始和方法之前。当然,它们也可以出现在其他位置,例如方法内。在函数或方法内的块注释应该和它们所描述的代码具有相同的缩进位置。

在块注释前加一个空行用来把它和代码的其余部分分开。

/*

* Here is a block comment.

*/

5.1.2单行注释

短的注释可以写在一行内,并且和后面的代码保持相同的缩进。在单行注释前应该加一个空行。下面是单行注释的例子:

if (condition) {


/* Handle the condition. */

...

}

5.1.3尾部注释

非常短的注释可以和它所注释的代码出现在同一行内,但是应该移动足够远,以把注释和语句分开。假如多行短注释出现在一块代码内,应该让它们排列整齐。像下面这样:

if (a == 2) {

return TRUE; /* special case */

} else {

return isPrime(a); /* works only for odd a */

}

5.1.4行末注释

“//”注释定界符可以注释在行外或行内,例如:

if (foo > 1) {


// Do a double-flip.

...

}

else {

return false; // Explain why here.

}

//if (bar > 1) {

//

// // Do a triple-flip.

// ...

//}

//else {

// return false;

//}

建议注释和代码不写在同一行内,所以尾部注释不被推荐。

5.2文档注释

请参考javadoc文档。

6.声明

6.1每行的数目

每行应仅有一个声明。不要把不同类型的声明放在同一行内,例如:

int foo, fooarray[]; //这样是错的

6.2初始化

本地变量在哪里声明就应该在哪里初始化。

6.3位置

请仅把声明放在块的开始。(一个块是指任何被一对大括号括起的代码。)不要等到变量第一次使用时才声明它们,那样会把粗心的编程人员搞糊涂,并且妨碍范围(块)内的代码迁移。

void myMethod() {

int int1 = 0; // beginning of method block


if (condition) {

int int2 = 0; // beginning of "if" block

...

}

}

这个准则的一个例外是for循环的索引变量:

for (int i = 0; i < maxLoops; i++) { ... }

应该避免本地声明对高层级声明的覆盖。例如,不要在一个方法内声明和类变量相同的变量名:

int count;

...

myMethod() {

if (condition) {

int count = 0; // AVOID!

...

}

...

}

6.4类和接口声明

书写类和接口时,应该遵守下面的这些格式准则:

· 在方法名和“(”之间没有空格

· “{”应该放在声明语句的末尾

· “}”在单独一行,并且和开头语句左对齐,除非大括号之间是空语句,这种情况,“}”紧接在“{”之后

class Sample extends Object {

int ivar1;

int ivar2;


Sample(int i, int j) {

ivar1 = i;

ivar2 = j;

}


int emptyMethod() {}


...

}

· 方法由空行隔开。

7.语句

7.1简单语句

每行至多包含一条语句。例如:

argv++; // Correct

argc--; // Correct

argv++; argc--; // AVOID!

7.2复合语句

复合语句包括一组被大括号括起来的语句。

· 嵌套在内层的语句应该比外层的语句缩进一级

· 左大括号应该放在开始语句的行的末尾,右大括号应该单独一行,并且和开始语句左对齐

· 当语句是控制结构(像if-else)的一部分时,在所有的语句外面添加大括号,包括单行。这样,当你增加一条语句时,不会因为忘记添加大括号而意外的造成程序错误。

7.3返回语句

除非想让返回结果看上去更明显,不需要在返回的值上面加圆括号。例如:

return;


return myDisk.size();


return (size ? size : defaultSize);

7.4 if else语句

像下面这样书写if else类的语句:

if (condition) {

statements;

}


if (condition) {

statements;

} else {

statements;

}


if (condition) {

statements;

} else if (condition) {

statements;

} else{

statements;

}

7.5 for语句

一个for语句写成下面这样:

for (initialization; condition; update) {

statements;

}

一个空的for语句写成这样:

for (initialization; condition; update);

在for语句的initialization和update子句中使用逗号操作符时,应该避免使用超过三个变量的过于复杂的子句。如果需要的话,应该把这些子句写到for语句之外。

7.6 while语句

一个while语句应该写成这样:

while (condition) {

statements;

}

一个空的while语句应该写成这样:

while (condition);

7.7 do-while语句

do {

statements;

} while (condition);

7.8 switch语句

一个switch语句写成下面这样:

switch (condition) {

case ABC:

statements;

/* falls through */


case DEF:

statements;

break;


case XYZ:

statements;

break;


default:

statements;

break;

}

7.9 try-catch语句

一个try-catch语句应该写成下面的格式:

try {

statements;

} catch (ExceptionClass e) {

statements;

}

一个try-catch语句可以接一个finally子句:

try {

statements;

} catch (ExceptionClass e) {

statements;

} finally {

statements;

}

8.空白

8.1空白行(空行)

通过把逻辑上相关的代码段用空白行分开,可以提高程序的可读性。

两行空白通常用于下面的情况:

· 在源文件的章节之间

· 在类或接口定义之间

一行空白则通常用于下面的情况:

· 方法之间

· 在方法中的本地变量声明和第一条语句之间

· 在块注释和单行注释之前

· 在方法内的逻辑片段之间

8.2空格

空格应该在下面这些情况下使用:

· 关键字和圆括号之间应该用空格分开,例如:

while (true) {

...

}

需要注意的是方法名和左括号之间不应该加空格,这样可以区分开关键字和方法调用。

· 参数列表的逗号之后应该加空格

· 除“.”之外的二元操作符都应该使用空格把它们和它们的操作数分开。不能在一元操作符和它们的操作数之间加空格。

a += c + d;

a = (a + b) / (c * d);


while (d++ = s++) {

n++;

}

printSize("size is " + foo + "\n");

· for语句的表达式之间应该用空格分开,例如:

for (expr1; expr2; expr3)

· 类型声明(cast)之后应该加空格,例如:

myMethod((byte) aNum, (Object) x);

myMethod((int) (cp + 5), ((int) (i + 3)) + 1);

9.命名规范

命名规范通过提高程序的可读性使程序更易理解。

标识符类型 命名原则 例子

包 包名的前缀由小写的ASCII字符书写,并且是顶级域名或者在ISO Standard 3166, 1981中指定的国家缩写。包名的其余部分则由组织内的命名习惯决定。 com.sun.eng com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese

类 类名应该是首字母大写的大小写混排(所谓大小写混排即每个单词首字母大写,其余字母小写)的名词。类名应该尽量简单并且是描述性的,不应该使用缩写,除非该缩写使用非常广泛,例如URL、HTML。 class Raster;class ImageSprite;

接口 接口的命名原则和类一样。 interface RasterDelegate;interface Storing;

方法 方法名应该是首字母小写的大小写混排的动词。 run();runFast();getBackground();

变量 变量名应该以首字母小写的大小写混排格式书写,变量名不应以“_”或“$”开头。变量名应该尽量短,并且是有意义的。给变量起名应该便于记忆,并且指明它的意图。只能在一些临时变量中使用单字母的命名,通用的名字有用于integer类型的i, j, k, m, n和用于char类型的c,d,e。 int i;char c;float myWidth;

常量 声明为类常量的变量名应该全部大写,每个单词间用下划线(“_”)隔开。 static final int MIN_WIDTH = 4; static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1;


11.代码举例

/*

* @(#)Blah.java 1.82 99/03/18

*

* Copyright (c) 1994-1999 Sun Microsystems, Inc.

* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.

* All rights reserved.

*

* This software is the confidential and proprietary information of Sun

* Microsystems, Inc. ("Confidential Information"). You shall not

* disclose such Confidential Information and shall use it only in

* accordance with the terms of the license agreement you entered into

* with Sun.

*/



package java.blah;


import java.blah.blahdy.BlahBlah;


/**

* Class description goes here.

*

* @version 1.82 18 Mar 1999

* @author Firstname Lastname

*/

public class Blah extends SomeClass {

/* A class implementation comment can go here. */


/** classVar1 documentation comment */

public static int classVar1;


/**

* classVar2 documentation comment that happens to be

* more than one line long

*/

private static Object classVar2;


/** instanceVar1 documentation comment */

public Object instanceVar1;


/** instanceVar2 documentation comment */

protected int instanceVar2;


/** instanceVar3 documentation comment */

private Object[] instanceVar3;


/**

* ...constructor Blah documentation comment...

*/

public Blah() {

// ...implementation goes here...

}


/**

* ...method doSomething documentation comment...

*/

public void doSomething() {

// ...implementation goes here...

}


/**

* ...method doSomethingElse documentation comment...

* @param someParam description

*/

public void doSomethingElse(Object someParam) {

// ...implementation goes here...

}

}

12.让一切变得更容易

如此多的规则真是让人头痛,难道在取得收益之前一定要付出代价吗?

噢,不用,因为已经有人为我们付出这些代价了。在此,请感谢这些好心人,他们就是热忱的和充满理想主义的开发源码的作者。

JRefactory是一个用于java代码重构的开放源码工程,它包含一个叫PrettyPrinter的java代码格式化(美化)工具,允许自定义格式,并且把定义的配置保存在pretty.settings配置文件中,这样,在组织内只需要一次设置共同遵守的格式规范,然后把JRefactory和pretty.settings发布到每个人的机器上,在书写代码的时候,使用该工具格式化,就得到了统一的编码格式,同时,它在格式化的时候需要分析文法,所以语法不对的程序会被检查出错。该工具可以完全产生Sun的上述规范,完全支持生成javadoc,并且支持多种IDE环境。

不过,它有一个bug,即解析中文的行末注释时可能出错,解决这个问题的方法很简单,把

//一些注释

修改成

/* 一些注释 */

虽然这样有点麻烦,但是相对它的好处来说,是算不了什么的。

你可能感兴趣的:(java,C++,c,C#,sun)