Java
語言編碼規范
(Java Code Conventions)
(sun)
?
本文:
http://www.vuu.cn/article/vuu.asp?item=20936
?
原文:
http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
目錄
1.1 為什么要有編碼規范(Why Have Code Conventions)2
3.1 Java源文件(Java Source Files)3
3.1.1 開頭注釋(Beginning Comments)3
3.1.2 包和引入語句(Package and Import Statements)4
3.1.3 類和接口聲明(Class and Interface Declarations)4
5.1 實現注釋的格式(Implementation Comment Formats)7
5.1.2 單行注釋(Single-Line Comments)8
5.1.3 尾端注釋(Trailing Comments)8
5.1.4 行末注釋(End-Of-Line Comments)8
5.2 文檔注釋(Documentation Comments)9
6.1 每行聲明變量的數量(Number Per Line)10
6.4 類和接口的聲明(Class and Interface Declarations)12
7.2 復合語句(Compound Statements)13
7.4 if,if-else,if else-if else語句(if, if-else, if else-if else Statements)13
7.6 while語句(while Statements)14
7.7 do-while語句(do-while Statements)15
7.8 switch語句(switch Statements)15
7.9 try-catch語句(try-catch Statements)16
10 編程慣例(Programming Practices)19
10.4 變量賦值(Variable Assignments)19
10.5 其它慣例(Miscellaneous Practices)20
10.5.2 返回值(Returning Values)21
1 介紹 (Introduction)
1.1 為什么要有編碼規范 (Why Have Code Conventions)
編碼規范對于程序員而言尤為重要,有以下幾個原因:
- 一個軟件的生命周期中, 80% 的花費在于維護
- 幾乎沒有任何一個軟件,在其整個生命周期中,均由最初的開發人員來維護
- 編碼規范可以改善軟件的可讀性,可以讓程序員盡快而徹底地理解新的代碼
- 如果你將源碼作為產品發布,就需要確任它是否被很好的打包并且清晰無誤,一如你已構建的其它任何產品
為了執行規范,每個軟件開發人員必須一致遵守編碼規范。每個人。
1.2 版權聲明 (Acknowledgments)
本文檔反映的是 Sun MicroSystems 公司, Java 語言規范中的編碼標準部分。主要貢獻者包括: Peter King , Patrick Naughton , Mike DeMoney , Jonni Kanerva , Kathy Walrath 以及 Scott Hommel 。
本文檔現由 Scott Hommel 維護,有關評論意見請發至 shommel@eng.sun.com
2 文件名 (File Names)
這部分列出了常用的文件名及其后綴。
2.1 文件后綴 (File Suffixes)
Java 程序使用下列文件后綴:
文件類別 文件后綴
Java 源文件 .java
Java 字節碼文件 .class
2.2 常用文件名 (Common File Names)
常用的文件名包括:
文件名 用途
GNUmakefile makefiles 的首選文件名。我們采用 gnumake 來創建( build )軟件。
README 概述特定目錄下所含內容的文件的首選文件名
3 文件組織 (File Organization)
一個文件由被空行分割而成的段落以及標識每個段落的可選注釋共同組成。超過 2000 行的程序難以閱讀,應該盡量避免。 "Java 源文件范例 " 提供了一個布局合理的 Java 程序范例。
3.1 Java 源文件 (Java Source Files)
每個 Java 源文件都包含一個單一的公共類或接口。若私有類和接口與一個公共類相關聯,可以將它們和公共類放入同一個源文件。公共類必須是這個文件中的第一個類或接口。
Java 源文件還遵循以下規則:
- 開頭注釋(參見 " 開頭注釋 " )
- 包和引入語句(參見 "包和引入語句" )
- 類和接口聲明(參見 "類和接口聲明" )
3.1.1
開頭注釋
(Beginning Comments)
所有的源文件都應該在開頭有一個 C 語言風格的注釋,其中列出類名、版本信息、日期和版權聲明:
? /*
?? * Classname
?? *
?? * Version information
?? *
?? * Date
?? *
?? * Copyright notice
?? */
3.1.2
包和引入語句
(Package and Import Statements)
在多數 Java 源文件中,第一個非注釋行是包語句。在它之后可以跟引入語句。例如:
? package java.awt;
? import java.awt.peer.CanvasPeer;
3.1.3
類和接口聲明
(Class and Interface Declarations)
下表描述了類和接口聲明的各個部分以及它們出現的先后次序。參見 "Java 源文件范例 " 中一個包含注釋的例子。
? 類 / 接口聲明的各部分 注解
1 類 / 接口文檔注釋 (/** …… */) 該注釋中所需包含的信息,參見 " 文檔注釋 "
2 類或接口的聲明 ??
3 類 / 接口實現的注釋 (/* …… */) 如果有必要的話 該注釋應包含任何有關整個類或接口的信息,而這些信息又不適合作為類 / 接口文檔注釋。
4 類的 ( 靜態 ) 變量 首先是類的公共變量,隨后是保護變量,再后是包一級別的變量 ( 沒有訪問修飾符, access modifier) ,最后是私有變量。
5 實例變量 首先是公共級別的,隨后是保護級別的,再后是包一級別的 ( 沒有訪問修飾符 ) ,最后是私有級別的。
6 構造器 ??
7 方法 這些方法應該按功能,而非作用域或訪問權限,分組。例如,一個私有的類方法可以置于兩個公有的實例方法之間。其目的是為了更便于閱讀和理解代碼。
4 縮進排版 (Indentation)
4 個空格常被作為縮進排版的一個單位。縮進的確切解釋并未詳細指定 ( 空格 vs. 制表符 ) 。一個制表符等于 8 個空格 ( 而非 4 個 ) 。
4.1 行長度 (Line Length)
盡量避免一行的長度超過 80 個字符,因為很多終端和工具不能很好處理之。
注意:用于文檔中的例子應該使用更短的行長,長度一般不超過 70 個字符。
4.2 換行 (Wrapping Lines)
當一個表達式無法容納在一行內時,可以依據如下一般規則斷開之:
- 在一個逗號后面斷開
- 在一個操作符前面斷開
- 寧可選擇較高級別 (higher-level) 的斷開,而非較低級別 (lower-level) 的斷開
- 新的一行應該與上一行同一級別表達式的開頭處對齊
- 如果以上規則導致你的代碼混亂或者使你的代碼都堆擠在右邊,那就代之以縮進 8 個空格。
以下是斷開方法調用的一些例子:
? someMethod(longExpression1, longExpression2, longExpression3,
?????????????????? longExpression4, longExpression5);
? var = someMethod1(longExpression1,
??????????????????????????? someMethod2(longExpression2,
?????????????????????????????????????????????? longExpression3));
以下是兩個斷開算術表達式的例子。前者更好,因為斷開處位于括號表達式的外邊,這是個較高級別的斷開。
? longName1 = longName2 * (longName3 + longName4 - longName5)
???????????????????? + 4 * longname6; //PREFFER
? longName1 = longName2 * (longName3 + longName4
???????????????????????????????????????? - longName5) + 4 * longname6; //AVOID
以下是兩個縮進方法聲明的例子。前者是常規情形。后者若使用常規的縮進方式將會使第二行和第三行移得很靠右,所以代之以縮進 8 個空格
? //CONVENTIONAL INDENTATION
? someMethod(int anArg, Object anotherArg, String yetAnotherArg,
??????????????????? Object andStillAnother) {
??? ...
? }
? //INDENT 8 SPACES TO AVOID VERY DEEP INDENTS
? private static synchronized horkingLongMethodName(int anArg,
????????? Object anotherArg, String yetAnotherArg,
????????? Object andStillAnother) {
??? ...
? }
?????
if 語句的換行通常使用 8 個空格的規則,因為常規縮進 (4 個空格 ) 會使語句體看起來比較費勁。比如:
? //DON’T USE THIS INDENTATION
? if ((condition1 && condition2)
????? || (condition3 && condition4)
????? ||!(condition5 && condition6)) { //BAD WRAPS
????? doSomethingAboutIt();???????????? //MAKE THIS LINE EASY TO MISS
? }
? //USE THIS INDENTATION INSTEAD
? if ((condition1 && condition2)
????????? || (condition3 && condition4)
????????? ||!(condition5 && condition6)) {
????? doSomethingAboutIt();
? }
? //OR USE THIS
? if ((condition1 && condition2) || (condition3 && condition4)
????????? ||!(condition5 && condition6)) {
????? doSomethingAboutIt();
? }
?????
這里有三種可行的方法用于處理三元運算表達式:
? alpha = (aLongBooleanExpression) ? beta : gamma;
? alpha = (aLongBooleanExpression) ? beta
?????????????????????????????????? : gamma;
? alpha = (aLongBooleanExpression)
????????? ? beta
????????? : gamma;
?????
5 注釋 (Comments)
Java 程序有兩類注釋:實現注釋 (implementation comments) 和文檔注釋 (document comments) 。實現注釋是那些在 C++ 中見過的,使用 /*...*/ 和 // 界定的注釋。文檔注釋 ( 被稱為 "doc comments") 是 Java 獨有的,并由 /**...*/ 界定。文檔注釋可以通過 javadoc 工具轉換成 HTML 文件。
實現注釋用以注釋代碼或者實現細節。文檔注釋從實現自由 (implementation-free) 的角度描述代碼的規范。它可以被那些手頭沒有源碼的開發人員讀懂。
注釋應被用來給出代碼的總括,并提供代碼自身沒有提供的附加信息。注釋應該僅包含與閱讀和理解程序有關的信息。例如,相應的包如何被建立或位于哪個目錄下之類的信息不應包括在注釋中。
在注釋里,對設計決策中重要的或者不是顯而易見的地方進行說明是可以的,但應避免提供代碼中己清晰表達出來的重復信息。多余的的注釋很容易過時。通常應避免那些代碼更新就可能過時的注釋。
注意:頻繁的注釋有時反映出代碼的低質量。當你覺得被迫要加注釋的時候,考慮一下重寫代碼使其更清晰。
注釋不應寫在用星號或其他字符畫出來的大框里。注釋不應包括諸如制表符和回退符之類的特殊字符。
5.1 實現注釋的格式 (Implementation Comment Formats)
程序可以有 4 種實現注釋的風格:塊 (block) 、單行 (single-line) 、尾端 (trailing) 和行末 (end-of-line) 。
5.1.1
塊注釋
(Block Comments)
塊注釋通常用于提供對文件,方法,數據結構和算法的描述。塊注釋被置于每個文件的開始處以及每個方法之前。它們也可以被用于其他地方,比如方法內部。在功能和方法內部的塊注釋應該和它們所描述的代碼具有一樣的縮進格式。
塊注釋之首應該有一個空行,用于把塊注釋和代碼分割開來,比如:
? /*
?? * Here is a block comment.
?? */
?????
塊注釋可以以 /*- 開頭,這樣 indent(1) 就可以將之識別為一個代碼塊的開始,而不會重排它。
? /*-
??? * Here is a block comment with some very special
??? * formatting that I want indent(1) to ignore.
??? *
??? * ???one
??? *??????? two
??? *??????????? three
??? */
?????
注意:如果你不使用 indent(1) ,就不必在代碼中使用 /*- ,或為他人可能對你的代碼運行 indent(1) 作讓步。
參見 " 文檔注釋 "
5.1.2
單行注釋
(Single-Line Comments)
短注釋可以顯示在一行內,并與其后的代碼具有一樣的縮進層級。如果一個注釋不能在一行內寫完,就該采用塊注釋 ( 參見 " 塊注釋 ") 。單行注釋之前應該有一個空行。以下是一個 Java 代碼中單行注釋的例子:
? if (condition) {
??? /* Handle the condition. */
??? ...
? }
?????
5.1.3
尾端注釋
(Trailing Comments)
極短的注釋可以與它們所要描述的代碼位于同一行,但是應該有足夠的空白來分開代碼和注釋。若有多個短注釋出現于大段代碼中,它們應該具有相同的縮進。
以下是一個 Java 代碼中尾端注釋的例子:
? if (a == 2) {
????? return TRUE;????????????? /* special case */
? } else {
????? return isPrime(a);???????? /* works only for odd a */
? }
?????
5.1.4
行末注釋
(End-Of-Line Comments)
注釋界定符 "http://" ,可以注釋掉整行或者一行中的一部分。它一般不用于連續多行的注釋文本;然而,它可以用來注釋掉連續多行的代碼段。以下是所有三種風格的例子:
? 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 文檔注釋 (Documentation Comments)
注意:此處描述的注釋格式之范例,參見 "Java 源文件范例 "
若想了解更多,參見 "How to Write Doc Comments for Javadoc" ,其中包含了有關文檔注釋標記的信息 (@return, @param, @see) :
http://java.sun.com/javadoc/writingdoccomments/index.html
若想了解更多有關文檔注釋和 javadoc 的詳細資料,參見 javadoc 的主頁:
http://java.sun.com/javadoc/index.html
文檔注釋描述 Java 的類、接口、構造器,方法,以及字段 (field) 。每個文檔注釋都會被置于注釋定界符 /**...*/ 之中,一個注釋對應一個類、接口或成員。該注釋應位于聲明之前:
? /**
??? * The Example class provides ...
??? */
? public class Example { ...
?????
注意頂層 (top-level) 的類和接口是不縮進的,而其成員是縮進的。描述類和接口的文檔注釋的第一行 (/**) 不需縮進;隨后的文檔注釋每行都縮進 1 格 ( 使星號縱向對齊 ) 。成員,包括構造函數在內,其文檔注釋的第一行縮進 4 格,隨后每行都縮進 5 格。
若你想給出有關類、接口、變量或方法的信息,而這些信息又不適合寫在文檔中,則可使用實現塊注釋
(
見
文檔注釋不能放在一個方法或構造器的定義塊中,因為 Java 會將位于文檔注釋之后的第一個聲明與其相關聯。
6 聲明 (Declarations)
6.1 每行聲明變量的數量 (Number Per Line)
推薦一行一個聲明,因為這樣以利于寫注釋。亦即,
? int level;? // indentation level
? int size;?? // size of table
?????
要優于,
int level, size;
不要將不同類型變量的聲明放在同一行,例如:
? int foo,? fooarray[];?? //WRONG!
?????
注意:上面的例子中,在類型和標識符之間放了一個空格,另一種被允許的替代方式是使用制表符:
? int??????? level;?? ??????// indentation level
? int??????? size;????????? // size of table
? Object??? currentEntry;? // currently selected table entry
?????
6.2 初始化 (Initialization)
盡量在聲明局部變量的同時初始化。唯一不這么做的理由是變量的初始值依賴于某些先前發生的計算。
6.3 布局 (Placement)
只在代碼塊的開始處聲明變量。(一個塊是指任何被包含在大括號 "{" 和 "}" 中間的代碼。)不要在首次用到該變量時才聲明之。這會把注意力不集中的程序員搞糊涂,同時會妨礙代碼在該作用域內的可移植性。
? 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 and Interface Declarations)
當編寫類和接口是,應該遵守以下格式規則:
- 在方法名與其參數列表之前的左括號 "(" 間不要有空格
- 左大括號 "{" 位于聲明語句同行的末尾
- 右大括號 "}" 另起一行,與相應的聲明語句對齊,除非是一個空語句, "}" 應緊跟在 "{" 之后
? class Sample extends Object {
????? int ivar1;
????? int ivar2;
????? Sample(int i, int j) {
????????? ivar1 = i;
????????? ivar2 = j;
????? }
????? int emptyMethod() {}
????? ...
? }
?????
- 方法與方法之間以空行分隔
7 語句 (Statements)
7.1 簡單語句 (Simple Statements)
每行至多包含一條語句,例如:
? argv++;?????? // Correct
? argc--;?????? // Correct
? argv++; argc--;?????? // AVOID!
?????
7.2 復合語句 (Compound Statements)
復合語句是包含在大括號中的語句序列,形如 "{ 語句 }" 。例如下面各段。
- 被括其中的語句應該較之復合語句縮進一個層次
- 左大括號 "{" 應位于復合語句起始行的行尾;右大括號 "}" 應另起一行并與復合語句首行對齊。
- 大括號可以被用于所有語句,包括單個語句,只要這些語句是諸如 if-else 或 for 控制結構的一部分。這樣便于添加語句而無需擔心由于忘了加括號而引入 bug 。
7.3 返回語句 (return Statements)
一個帶返回值的 return 語句不使用小括號 "()" ,除非它們以某種方式使返回值更為顯見。例如:
? return;
? return myDisk.size();
? return (size ? size : defaultSize);
?????
7.4 if , if-else , if else-if else 語句 (if, if-else, if else-if else Statements)
if-else 語句應該具有如下格式:
? if (condition) {
????? statements;
? }
? if (condition) {
????? statements;
? } else {
????? statements;
? }
? if (condition) {
????? statements;
? } else if (condition) {
????? statements;
? } else{
????? statements;
? }
?????
注意: if 語句總是用 "{" 和 "}" 括起來,避免使用如下容易引起錯誤的格式:
? if (condition) //AVOID! THIS OMITS THE BRACES {}!
????? statement;
?????
7.5 for 語句 (for Statements)
一個 for 語句應該具有如下格式:
? for (initialization; condition; update) {
????? statements;
? }
?????
一個空的 for 語句 ( 所有工作都在初始化,條件判斷,更新子句中完成)應該具有如下格式:
? for (initialization; condition; update);
?????
當在 for 語句的初始化或更新子句中使用逗號時,避免因使用三個以上變量,而導致復雜度提高。若需要,可以在 for 循環之前 ( 為初始化子句 ) 或 for 循環末尾 ( 為更新子句 ) 使用單獨的語句。
7.6 while 語句 (while Statements)
一個 while 語句應該具有如下格式
? while (condition) {
????? statements;
? }
?????
一個空的 while 語句應該具有如下格式:
? while (condition);
?????
7.7 do-while 語句 (do-while Statements)
一個 do-while 語句應該具有如下格式:
? do {
????? statements;
? } while (condition);
?????
7.8 switch 語句 (switch Statements)
一個 switch 語句應該具有如下格式:
? switch (condition) {
? case ABC:
??? ??statements;
????? /* falls through */
? case DEF:
????? statements;
????? break;
? case XYZ:
????? statements;
????? break;
? default:
????? statements;
????? break;
? }
?????
每當一個 case 順著往下執行時 ( 因為沒有 break 語句 ) ,通常應在 break 語句的位置添加注釋。上面的示例代碼中就包含注釋 /* falls through */ 。
7.9 try-catch 語句 (try-catch Statements)
一個 try-catch 語句應該具有如下格式:
? try {
????? statements;
? } catch (ExceptionClass e) {
????? statements;
? }
?????
一個 try-catch 語句后面也可能跟著一個 finally 語句,不論 try 代碼塊是否順利執行完,它都會被執行。
? try {
????? statements;
? } catch (ExceptionClass e) {
????? statements;
? } finally {
????? statements;
? }
?????
8 空白 (White Space)
8.1 空行 (Blank Lines)
空行將邏輯相關的代碼段分隔開,以提高可讀性。
下列情況應該總是使用兩個空行:
- 一個源文件的兩個片段 (section) 之間
- 類聲明和接口聲明之間
下列情況應該總是使用一個空行:
- 兩個方法之間
- 方法內的局部變量和方法的第一條語句之間
-
塊注釋(參見
"
- 一個方法內的兩個邏輯段之間,用以提高可讀性
8.2 空格 (Blank Spaces)
下列情況應該使用空格:
- 一個緊跟著括號的關鍵字應該被空格分開,例如:
? while (true) {
????? ...
? }
?????
注意:空格不應該置于方法名與其左括號之間。這將有助于區分關鍵字和方法調用。
- 空白應該位于參數列表中逗號的后面
- 所有的二元運算符,除了 "." ,應該使用空格將之與操作數分開。一元操作符和操作數之間不因該加空格,比如:負號 ("-") 、自增 ("++") 和自減 ("--") 。例如:
??? a += c + d;
??? a = (a + b) / (c * d);
??? while (d++ = s++) {
??????? n++;
??? }
??? printSize("size is " + foo + "\n");
?????
- for 語句中的表達式應該被空格分開,例如:
??? for (expr1; expr2; expr3)
?????
- 強制轉型后應該跟一個空格,例如:
? ?? myMethod((byte) aNum, (Object) x);
??? myMethod((int) (cp + 5), ((int) (i + 3)) + 1);
?????
9 命名規范 (Naming Conventions)
命名規范使程序更易讀,從而更易于理解。它們也可以提供一些有關標識符功能的信息,以助于理解代碼,例如,不論它是一個常量,包,還是類。
標識符類型 命名規則 例子
包 (Packages) 一個唯一包名的前綴總是全部小寫的 ASCII 字母并且是一個頂級域名,通常是 com , edu , gov , mil , net , org ,或 1981 年 ISO 3166 標準所指定的標識國家的英文雙字符代碼。包名的后續部分根據不同機構各自內部的命名規范而不盡相同。這類命名規范可能以特定目錄名的組成來區分部門 (department) ,項目 (project) ,機器 (machine) ,或注冊名 (login names) 。 com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
類 (Classes) 命名規則:類名是個一名詞,采用大小寫混合的方式,每個單詞的首字母大寫。盡量使你的類名簡潔而富于描述。使用完整單詞,避免縮寫詞 ( 除非該縮寫詞被更廣泛使用,像 URL , HTML) class Raster;
class ImageSprite;
接口 (Interfaces) 命名規則:大小寫規則與類名相似 interface RasterDelegate;
interface Storing;
方法 (Methods) 方法名是一個動詞,采用大小寫混合的方式,第一個單詞的首字母小寫,其后單詞的首字母大寫。 run();
runFast();
getBackground();
變量 (Variables) 除了變量名外,所有實例,包括類,類常量,均采用大小寫混合的方式,第一個單詞的首字母小寫,其后單詞的首字母大寫。變量名不應以下劃線或美元符號開頭,盡管這在語法上是允許的。
變量名應簡短且富于描述。變量名的選用應該易于記憶,即,能夠指出其用途。盡量避免單個字符的變量名,除非是一次性的臨時變量。臨時變量通常被取名為 i , j , k , m 和 n ,它們一般用于整型; c , d , e ,它們一般用于字符型。 char c;
int i;
float myWidth;
實例變量 (Instance Variables) 大小寫規則和變量名相似,除了前面需要一個下劃線 int _employeeId;
String _name;
Customer _customer;
常量 (Constants) 類常量和 ANSI 常量的聲明,應該全部大寫,單詞間用下劃線隔開。 ( 盡量避免 ANSI 常量,容易引起錯誤 ) static final int MIN_WIDTH = 4;
static final int MAX_WIDTH = 999;
static final int GET_THE_CPU = 1;
10 編程慣例 (Programming Practices)
10.1 提供對實例以及類變量的訪問控制 (Providing Access to Instance and Class Variables)
若沒有足夠理由,不要把實例或類變量聲明為公有。通常,實例變量無需顯式的設置 (set) 和獲取 (gotten) ,通常這作為方法調用的邊緣效應 (side effect) 而產生。
一個具有公有實例變量的恰當例子,是類僅作為數據結構,沒有行為。亦即,若你要使用一個結構 (struct) 而非一個類 ( 如果 java 支持結構的話 ) ,那么把類的實例變量聲明為公有是合適的。
10.2 引用類變量和類方法 (Referring to Class Variables and Methods)
避免用一個對象訪問一個類的靜態變量和方法。應該用類名替代。例如:
? classMethod();???????????? //OK
? AClass.classMethod();????? //OK
? anObject.classMethod();??? //AVOID!
?????
10.3 常量 (Constants)
位于 for 循環中作為計數器值的數字常量,除了 -1,0 和 1 之外,不應被直接寫入代碼。
10.4 變量賦值 (Variable Assignments)
避免在一個語句中給多個變量賦相同的值。它很難讀懂。例如:
? fooBar.fChar = barFoo.lchar = 'c'; // AVOID!
?????
不要將賦值運算符用在容易與相等關系運算符混淆的地方。例如:
? if (c++ = d++) {??????? // AVOID! (Java disallows)
????? ...
? }
?????
應該寫成
? if ((c++ = d++) != 0) {
??? ...
? }
?????
不要使用內嵌 (embedded) 賦值運算符試圖提高運行時的效率,這是編譯器的工作。例如:
? d = (a = b + c) + r;??????? // AVOID!
?????
應該寫成
? a = b + c;
? d = a + r;
?????
10.5 其它慣例 (Miscellaneous Practices)
10.5.1
圓括號
(Parentheses)
一般而言,在含有多種運算符的表達式中使用圓括號來避免運算符優先級問題,是個好方法。即使運算符的優先級對你而言可能很清楚,但對其他人未必如此。你不能假設別的程序員和你一樣清楚運算符的優先級。
? if (a == b && c == d)???? // AVOID!
? if ((a == b) && (c == d))? // RIGHT
?????
10.5.2
返回值
(Returning Values)
設法讓你的程序結構符合目的。例如:
? if (booleanExpression) {
????? return true;
? } else {
????? return false;
? }
?????
應該代之以如下方法:
? return booleanExpression;
?????
類似地:
? if (condition) {
????? return x;
? }
? return y;
?????
應該寫做:
? return (condition ? x : y);
?????
如果一個包含二元運算符的表達式出現在三元運算符 " ? : " 的 "?" 之前,那么應該給表達式添上一對圓括號。例如:
? (x >= 0) ? x : -x;
?????
在注釋中使用 XXX 來標識某些未實現 (bogus) 的但可以工作 (works) 的內容。用 FIXME 來標識某些假的和錯誤的內容。
11 代碼范例 (Code Examples)
11.1 Java 源文件范例 (Java Source File Example)
下面的例子,展示了如何合理布局一個包含單一公共類的 Java 源程序。接口的布局與其相似。更多信息參見 " 類和接口聲明 " 以及 " 文擋注釋 " 。
/*
?* @(#)Blah.java??????? 1.82
?*
?* Copyright (c) 1994-1999 Sun Microsystems, Inc.
?*
?* 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...
??? }
}