Java編碼規範(常用重點)

1、Java源文件

1.1、註釋

所有的源文件都應當在開頭有一個註釋,此中列出類名、版本信息、日期和版本聲明,具體可以參考我的博客:Java註釋模版設置

1.2、包和引入語句

大部分java源文件中,第一行非註釋行是包語句,在它之後可以跟引入語句,例如:

package com.org.jojo;

import java.io.Serializable;

2、縮進排版

4個空格常被作爲縮進排版的一個單位。縮進的確切聲明並未具體指定(空格 vs. 製表符)。一個製表符便是8個空格(而非4個)。

2.1、行長度

儘量避免一行的長度跨越80個字符,因爲很多終端和對象不能很好的處理。
注意:用於文檔中的例子應當應用更短的行長,長度一般不跨越70個字符。

2.2、換行

當一個表達式無法容納在一行內時,可以根據如下一般規矩斷開:

  • 在一個逗號後面斷開
  • 在一個操縱符前面斷開
  • 寧可選擇較高級別(higher-level)的斷開,而非較初級別(lower-level)的斷開
  • 新的一行應當與上一行同一級別表達式的開首處對齊
  • 若是以上規矩導致你的代碼雜沓或者使你的代碼都堆擠在右邊,那就代之以縮進8個空格。
someMethod(longExpression1, longExpression2, longExpression3,
           longExpression4, longExpression5);

var = someMethod1(longExpression1,
                  someMethod2(longExpression2,
                              longExpression3));

以下是兩個斷開算術表達式的例子。前者更好,因爲斷開處位於括號表達式的外邊,這是個較高級別外斷開。

longName1 = longName2 * (longName3 + longName4 - longName5)
            + 4 * longname6; //合適

longName1 = longName2 * (longName3 + longName4
                         - longName5) + 4 * longname6; //避免

以下是兩個縮進辦法聲明的例子。前者是常規情況。後者若應用常規的縮進體式格式將會使第二行和第三行移得很靠右,所以代之以縮進8個空格

//傳統的縮進
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
           Object andStillAnother) {
    ...
}

//8個縮進避免產生很深的縮進
private static synchronized horkingLongMethodName(int anArg,
        Object anotherArg, String yetAnotherArg,
        Object andStillAnother) {
    ...
}

if語句的換行凡是應用8個空格的規矩,因爲常規縮進(4個空格)會使語句體看起來鬥勁費勁。比如:

//不要使用這種縮進
if ((condition1&& condition2)
    || (condition3 && condition4)
    ||!(condition5 && condition6)) { //不合理
    doSomethingAboutIt();            //導致這行容易被忽略
}

//使用這種縮進代替
if ((condition1&& condition2)
        || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}

//或者使用這個
if ((condition1&& condition2) || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}

這裏有三種可行的辦法用於處理三元運算表達式:

alpha = (aLongBooleanExpression) ? beta : gamma;

alpha = (aLongBooleanExpression) ? beta
                                 : gamma;

alpha = (aLongBooleanExpression)
        ? beta
        : gamma;

3、註釋

Java程序有兩類註釋:實現註釋(implementation comments)和文檔註釋(document comments)。實現註釋是那些在C++中見過的,應用//和//界定的註釋。文檔註釋(被稱爲”doc comments”)是Java獨有的,並由/*…/界定。文檔註釋可以經由過程javadoc對象轉換成HTML文件。

實現註釋用以註釋代碼或者實現細節。文檔註釋從實現的角度描述代碼的規範。它可以被那些手頭沒有源碼的開闢人員讀懂。

註釋應被用來給出代碼的總括,並供給代碼自身沒有供給的附加信息。註釋應當僅包含與瀏覽和懂得程序有關的信息。例如,響應的包如何被建樹或位於哪個目次下之類的信息不該包含在註釋中。

在註釋裏,對設計決定計劃中首要的或者不是顯而易見的地方所進行聲明是可以的,但應避免給代碼中已清楚表達出來的反覆信息。不可標註多餘的的註釋。應避免那些代碼更新就可能過期的註釋。

注意:頻繁的註釋有時反應出代碼的低質量。當你感覺被迫要加註釋的時辰,推敲一下重寫代碼使其更清楚。

註釋不該寫在用星號或其他字符畫出來的大框裏。註釋不該包含諸如製表符和回退符之類的特別字符。

3.1、實現註釋的格局

程序可以有4種實現註釋的風格:塊(block)、單行(single-line)、尾端(trailing)和行末(end-of-line)。

3.1.1、塊註釋

塊註釋一般是對文件、辦法、數據佈局和算法的描述。塊註釋被置於每個文件的開端處以及每個方法之前。它們也可以被用於其他之處,比如方法內部。在功能和方法內部的塊註釋應當和它們所描述的代碼具有一樣的縮進格局。

塊註釋之前應當有一個空行,用於把塊註釋和代碼分別開來,比如:

 /*
  * 這是一個塊註釋
  */

塊註釋可以以/*-開頭,比如indent(1)就可以將其認爲一個代碼塊的開端,而不會覆蓋它。

 /*-
   * 這是一種比較特殊的塊註釋
   * 用indent(1)進行代碼格式化
   *
   *    one
   *        two
   *            three
   */

注意:若是你不應用indent(1),就不必在代碼中應用/*-,或爲他人可能對你的代碼運行indent(1)作讓步。

另見”文檔註釋”

3.1.2、單行註釋

短註釋可以顯示在一行內,並與之後的代碼具有一樣的縮進層級。若是一個註釋不能在一行內寫完,就該採取塊註釋(見”塊註釋”)。單行註釋之前應當有一個空行。以下是一個Java代碼中單行註釋的例子:

if (condition) {

    /* Handle thecondition. */
    ...
}
3.1.3、尾端註釋

極短的註釋可以與它們所要描述的代碼位於同一行,當然應當有足夠的空白來分隔代碼和註釋。若有多個短註釋呈現於大段代碼中,它們應當具有同樣的縮進。

以下是一個Java代碼中尾端註釋的例子:

if (a == 2) {
    return TRUE;            /* 註釋 */
} else {
    return isPrime(a);      /* 只標註這一行 */
}
3.1.4、行末註釋

註釋界定符”//”,可以註釋掉整行或者一行中的一項目組。以下是所有三種風格的例子:

if (foo > 1) {

    // Do adouble-flip.
    ...
} else {
    return false;          // Explain why here.
}

//if (bar > 1){
//
//    // Do a triple-flip.
//    ...
//} else {
//    return false;
//}

3.2、文檔註釋

注意:此處描述的註釋格局,另見”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的類、接口、構造器,方法,以及字段。每個文檔註釋都被置於註釋定界符/*…/之中,一個註釋對應一個類、接口或成員。該註釋應位於聲明之前:

/**
  * 提供 class 示例 ...
  */
  public classExample { ...

注意外層(top-level)的類和接口是不縮進的,而其成員是縮進的。描述類和接口的文檔註釋的第一行(/**)不需縮進;隨後的文檔註釋每行都縮進1格(使星號縱向對齊)。成員,包含構造函數在內,其文檔註釋的第一行縮進4格,隨後每行都縮進5格。

若你想給出有關類、接口、變量或方法的信息,而這些信息又不合適寫在文檔中,則可應用實現塊註釋(見3.1.1)或緊跟在聲明後面的單行註釋(見3.1.2)。例如,有關一個類實現的細節,應放入緊跟在類聲明後面的實現塊註釋中,而不是放在文檔註釋中。

文檔註釋不可放在一個方法或構造器的定義塊中,因爲Java會將位於文檔註釋之後的第一個聲明與其關聯。

4、聲明

4.1、每行聲明變量的數量

推薦一行一個聲明,因爲這樣有利於寫註釋。即,

int level;  // 等級
int size;   // 表格的大小

要優於:

int level, size;

不要將不同類型變量的聲明放在同一行,例如:

int foo,  fooarray[];  //錯誤!

注意:上面的例子中,在類型和標識符之間放了一個空格,還可以使用製表符來進行格式的調整:

int          level;         // 等級
int          size;          // 表格的大小
Object       currentEntry;  // 表格的當前項

4.2、初始化

儘量在聲明局部變量的同時初始化。

4.3、佈局

只在代碼塊的開始處聲明變量。(一個塊是指被包含在大括號”{“和”}”中心的代碼。)不要在第一次用到該變量時才聲明。這會把注意力不集中的程序員搞糊塗,同時會降低該代碼塊的可移植性。

void myMethod() {
    int int1 = 0;         // 方法代碼塊的開始

    if (condition) {
        int int2 = 0;     // "if"代碼塊的開始
        ...
    }
}

for 循環中的索引變量是一個例外:

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

避免聲明的局部變量覆蓋上一級聲明的變量,不要在內部代碼塊中聲明相同的變量名:

int count;
...
myMethod() {
    if (condition) {
        int count= 0;     // 避免!
        ...
    }
    ...
}

4.4、類和接口的聲明

當編寫類和接口時,應當遵守以下規矩:

  • 方法名和參數列表之前的左括號”(”間不要有空格
  • 左大括號”{“位於聲明類或方法的末尾
  • 右大括號”}”另起一行,與響應的聲明語句對齊,除非是一個空語句,”}”應緊跟在”{“之後
  • 方法與方法之間以空行分隔
class Sample extends Object {
    int ivar1;
    int ivar2;

    Sample(int i, int j) {
        ivar1 = i;
        ivar2 = j;
    }

    int emptyMethod() {}

    ...
}

5、語句

5.1、簡單語句

每行最多包含一條語句,例如:

argv++;       // 正確的
argc--;       // 正確的
argv++; argc--;       // 避免!

5.2、複合語句

複合語句是包含在大括號中的語句,形如”{ 語句 }”。例如:

  • 括號語句的內容應在上一級語句的前提下加一個縮進
  • 左大括號”{“應位於複合語句開始端行的行尾;右大括號”}”應另起一行並與複合語句首行對齊。
  • 大括號可以被用於所有語句,包含單個語句,只要這些語句是諸如if-else或for一類的。以便避免添加語句的時候忘記加括號。

5.3、返回語句

一個帶返回值的return語句不應用小括號”()”,除非它們以某種體式格式使返回值更爲顯見。例如:

return;

return myDisk.size();

return (size ? size : defaultSize);

5.4、if,if-else,if else-if else語句

if-else語句應當具有如下格局:

if (condition) {
    statements;
}

if (condition) {
    statements;
} else {
    statements;
}

if (condition) {
    statements;
} else if (condition) {
    statements;
} else {
    statements;
}

注意:if語句老是用”{“和”}”括起來,避免引起錯誤的格局:

if (condition)// 避免
    statement;

5.5、for語句

一個for語句應當具有如下格局:

for (initialization; condition; increment) {
    statements;
}

一個空的for語句應當具有如下格局:

for (initialization; condition; increment);

當在for語句的初始化或更新子句中應用逗號時,避免因應用三個以上變量,而導致複雜。若須要,可以在for循環之前(爲初始化子句)或for循環末尾(爲更新子句)應用其它的語句。

5.6、while語句

一個while語句應當具有如下格局

while (condition) {
    statements;
}

一個空的while語句應當具有如下格局:

while (condition);

5.7、do-while語句

一個do-while語句應當具有如下格局:

do {
    statements;
} while (condition);

5.8、switch語句

一個switch語句應當具有如下格局:

switch (condition) {
case ABC:
    statements;

case DEF:
    statements;
    break;

case XYZ:
    statements;
    break;

default:
    statements;
    break;
}

每當一個case順着往下運行時(因爲沒有break語句),在break語句的地方添加註釋。

5.9、try-catch語句

一個try-catch語句應當具有如下格局:

try {
    statements;
} catch (ExceptionClass e) {
    statements;
}

一個try-catch語句後面也可能跟着一個finally語句,無論try代碼塊是否順利執行完,它都被執行。

try {
    statements;
} catch (ExceptionClass e) {
    statements;
} finally {
    statements;
}

6、空白

6.1、空行

空行將邏輯相關的代碼段分隔開,以提高可讀性。

下列情景經常應用兩個空行:

  • 一個源文件的兩個片段(section)之間
  • 類聲明和接口聲明之間

下列情景經常應用一個空行:

  • 兩個方法之間
  • 方法內的局部變量和方法的第一條語句之間
  • 塊註釋(見”3.1.1”)或單行註釋(見”3.1.2”)之前
  • 一個方法內的兩個邏輯塊之間,用以提高可讀性

6.2、空格

下列情景應當使用空格:

  • 一個緊跟着括號的關鍵字應當被空格分隔,例如:
while (true) {
        ...
}

注意:空格不該置於方法名與其左括號之間。這將有助於區分關鍵字和辦法調用。

  • 空白應當位於參數列表中逗號的後面
  • 所有的二元運算符,除了”.”,應當使用空格將操作符和變量分開。一元操縱符和變量之間不加空格,比如:負號(”-“)、自增(”++”)和自減(”–”)。例如:
 a += c + d;
    a = (a + b) /(c * d);

    while (d++ = s++) {
        n++;
    }
    printSize("size is " + foo + "
");
  • for語句中的表達式應當被空格分隔,例如:
for (expr1; expr2; expr3)
  • 強制類型轉換後應當跟一個空格,例如:
 myMethod((byte) aNum, (Object) x);

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

7、命名規範

命名規範使程序更易讀,從而更易於懂得。它們也可以提供一些有關標識符功能的信息,有助於懂得代碼,無論它是一個常量,包,還是類。

標識符類型 命名規範 例子
一個獨立包名的前綴都是全部小寫的ASCII字母並且是一個域名,凡是com,edu,gov,mil,net,org,或1981年 ISO 3166標準所指定的標識國度的英文雙字符代碼。包名的後續按照不同機構各自內部的定名規範而不同。這類定名規範可以特定名的構成來區分部門(department),項目(project),機械(machine),或註冊名(login names)。 com.sun.engcom.apple.quicktime.v2 edu.cmu.cs.bovik.cheese
命名規範:類名是個一名詞,採取大小寫混淆的體式格式,每個單詞的首字母大寫。儘量使你的類名簡潔而富於描述。應用完全單詞,避免縮寫詞(除非該縮寫詞被更廣泛應用,像URL,HTML) class Raster; class ImageSprite;
接口 命名規範:大小寫規範與類名類似 interface RasterDelegate; interface Storing;
方法 方法名是一個動詞,採取大小寫混淆的體式格式,第一個單詞的首字母小寫,之後單詞的首字母大寫。 run(); runFast(); getBackground();
變量 除了變量名外,所有實例,包含類,類常量,均採取大小寫混淆的體式格式,第一個單詞的首字母小寫,之後單詞的首字母大寫。變量名不該以下劃線或美元符號開頭,儘管這在語法上是允許的。變量名應簡短且富於描述。變量名的選用應當易於記憶。儘量避免單個字符的變量名,除非是一次性的臨時變量。臨時變量凡是被取名爲i,j,k,m和n,它們一般用於整型;c,d,e,它們一般用於字符型。 char c; int i; float myWidth;
實例變量 大小寫規範和變量名類似,除了前面須要一個下劃線 int _employeeId; String _name; Customer _customer;
常量 類常量和ANSI常量的聲明,應當全部大寫,單詞間用下劃線隔開。(儘量避免ANSI常量,輕易引起錯誤) static final int MIN_WIDTH = 4; static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1;

8、編程實踐

8.1、實例以及類變量

若沒有足夠的理由,不要把實例或類變量聲明爲公有的。實例變量無需顯式的設置(set)和獲取(get)。

8.2、引用類變量和類辦法

避免用一個對象調用一個類的靜態變量和靜態辦法。應當用類名調換。例如:

classMethod();             //OK
AClass.classMethod();      //OK
anObject.classMethod();    //避免!

8.3、常量

位於for循環中作爲初始值的數字常量,除了-1,0和1之外,不該被直接寫入代碼。

8.4、變量賦值

避免在一個語句中給多個變量賦同樣的值。它很難讀懂。例如:

fooBar.fChar = barFoo.lchar = 'c'; // 避免!

不要將賦值運算符和關係運算符混用。例如:

if (c = d++) {        // 避免! (Java 不認可)
    ...
}

應當寫成

if ((c = d++) != 0) {
    ...
}

不要使用內嵌賦值運算符試圖提高運行的效率,這是編譯器的工作。例如:

d = (a = b + c) + r;        // 避免!

應當寫成

a = b + c;
d = a + r;

8.5、其它實戰

8.5.1、圓括號

一般而言,在含有多種運算符的表達式中應用圓括號來避免運算符優先級問題是個好辦法。即使運算符的優先級對你而言可能很清楚,但對其他人未必如此。你不能假設其他程序員和你一樣清楚運算符的優先級。

if (a == b && c == d)      // 避免!
if ((a == b) && (c == d))  // 正確
8.5.2、返回值

設法讓你的程序佈局合適目標。例如:

if (booleanExpression) {
    return true;
} else {
    return false;
}

應當使用如下方法:

return booleanExpression;

類似地:

if (condition) {
    return x;
}
return y;

應當寫成:

return (condition ? x : y);
8.5.3、三目運算符”?”前的表達式

若是一個包含二元運算符的表達式的三元運算符” ? : “的”?”之前,那麼應當給表達式添上一對圓括號。例如:

(x >= 0) ? x : -x;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章