1. 程式人生 > >初級程式設計師需要知道的基本程式碼規範

初級程式設計師需要知道的基本程式碼規範

  • 1.【強制】大括號的使用約定。如果是大括號內為空,則簡潔地寫成{}即可,不需要換行;如果是非空程式碼塊則:
        1) 左大括號前不換行。
        2) 左大括號後換行。
        3) 右大括號前換行。
        4) 右大括號後還有 else 等程式碼則不換行;表示終止的右大括號後必須換行。

  • 2.【強制】 左小括號和字元之間不出現空格;同樣,右小括號和字元之間也不出現空格。詳見第 5 條下方正例提示。
        反例:if (空格 a == b 空格)

  • 3.【強制】if/for/while/switch/do 等保留字與括號之間都必須加空格。

  • 4.【強制】任何二目、三目運算子的左右兩邊都需要加一個空格。
        說明:運算子包括賦值運算子=、邏輯運算子&&、加減乘除符號等。

  • 5.【強制】採用 4 個空格縮排,禁止使用 tab 字元。
        說明:如果使用 tab 縮排,必須設定 1 個 tab 為 4 個空格。IDEA 設定 tab 為 4 個空格時,
    請勿勾選 Use tab character;而在 eclipse 中,必須勾選 insert spaces for tabs。
    正例: (涉及上面五點)

    public static void main(String[] args) { 
        // 縮排 4 個空格 
        String say = "hello"; 
        // 運算子的左右必須有一個空格 
        int flag = 0; 
     
        // 關鍵詞 if 與括號之間必須有一個空格,括號內的 f 與左括號,0 與右括號不需要空格 
        if (flag == 0) { 
            System.out.println(say); 
        } 
     
        // 左大括號前加空格且不換行;左大括號後換行 
        if (flag == 1) { 
            System.out.println("world"); 
        // 右大括號前換行,右大括號後有 else,不用換行 
        } else { 
            System.out.println("ok"); 
        // 在右大括號後直接結束,則必須換行 
        } 
    }     
    
  • 6.【強制】註釋的雙斜線與註釋內容之間有且僅有一個空格。
      正例:// 註釋內容,注意在//和註釋內容之間有一個空格。

  • 7.【強制】單行字元數限制不超過 120 個,超出需要換行,換行時遵循如下原則:
        1) 第二行相對第一行縮排 4 個空格,從第三行開始,不再繼續縮排,參考示例。
        2) 運算子與下文一起換行。
        3) 方法呼叫的點符號與下文一起換行。
        4) 方法呼叫時,多個引數,需要換行時,在逗號後進行。
        5) 在括號前不要換行,見反例。

    • 正例:
      		StringBuffer sb = new StringBuffer(); 
      		// 超過 120 個字元的情況下,換行縮排 4 個空格,點號和方法名稱一起換行
      		sb.append("zi").append("xin")... 
      		    .append("huang")... 
      		    .append("huang")... 
      		    .append("huang");
      
    • 反例:
      		StringBuffer sb = new StringBuffer(); 
      		// 超過 120 個字元的情況下,不要在括號前換行
      		sb.append("zi").append("xin")...append 
      		    ("huang"); 
      		    
      		// 引數很多的方法呼叫可能超過 120 個字元,不要在逗號前換行
      		method(args1, args2, args3, ... 
      		    , argsX); 
      
  • 8.【強制】方法引數在定義和傳入時,多個引數逗號後邊必須加空格。
    正例:下例中實參的"a",後邊必須要有一個空格。
    method("a", "b", "c");

  • 9.【強制】IDE 的 text file encoding 設定為 UTF-8; IDE 中檔案的換行符使用 Unix 格式,不要使用 Windows 格式。

  • 10.【推薦】沒有必要增加若干空格來使某一行的字元與上一行對應位置的字元對齊。
     正例:

    	    int a = 3; 
    	    long b = 4L; 
    	    float c = 5F; 
    	    StringBuffer sb = new StringBuffer(); 
    

說明:增加 sb 這個變數,如果需要對齊,則給 a、b、c 都要增加幾個空格,在變數比較多的情況下,是一種累贅的事情。

  • 11.【推薦】方法體內的執行語句組、變數的定義語句組、不同的業務邏輯之間或者不同的語義之間插入一個空行。相同業務邏輯和語義之間不需要插入空行。
      說明:沒有必要插入多個空行進行隔開。

  • 【強制】避免通過一個類的物件引用訪問此類的靜態變數或靜態方法,無謂增加編譯器解析成本,直接用類名來訪問即可。

  • 【強制】不能使用過時的類或方法。
      說明:java.net.URLDecoder中的方法 decode(String encodeStr) 這個方法已經過時,應該使用雙引數 decode(String source, String encode)。介面提供方既然明確是過時介面,那麼有義務同時提供新的介面;作為呼叫方來說,有義務去考證過時方法的新實現是什麼。

  • 【強制】Object 的 equals 方法容易拋空指標異常,應使用常量或確定有值的物件來呼叫equals。
        正例:"test".equals(object);
        反例:object.equals("test");
      說明:推薦使用 java.util.Objects#equals(JDK7 引入的工具類)

  • 【強制】所有的相同型別的包裝類物件之間值的比較,全部使用 equals 方法比較。
      說明:對於 Integer var = ? 在-128 至 127 範圍內的賦值,Integer 物件是在 IntegerCache.cache 產生,會複用已有物件,這個區間內的 Integer 值可以直接使用==進行 判斷,但是這個區間之外的所有資料,都會在堆上產生,並不會複用已有物件,這是一個大坑,推薦使用 equals 方法進行判斷。

  • 【強制】構造方法裡面禁止加入任何業務邏輯,如果有初始化邏輯,請放在 init 方法中。

  • 【強制】POJO 類必須寫 toString 方法。使用 IDE 的中工具:source> generate toString時,如果繼承了另一個 POJO 類,注意在前面加一下 super.toString。
      說明:在方法執行丟擲異常時,可以直接呼叫 POJO 的 toString()方法列印其屬性值,便於排查問題。

  • 【推薦】使用索引訪問用 String 的 split 方法得到的陣列時,需做最後一個分隔符後有無內容的檢查,否則會有拋 IndexOutOfBoundsException 的風險。
      說明:

    		String str = "a,b,c,,"; 
    		String[] ary = str.split(","); 
    		// 預期大於 3,結果是 3
    		System.out.println(ary.length); 
    
  • 【推薦】當一個類有多個構造方法,或者多個同名方法,這些方法應該按順序放置在一起,便於閱讀,此條規則優先於第 15 條規則。

  • 15.【推薦】 類內方法定義順序依次是:公有方法或保護方法 > 私有方法 > getter/setter方法。
            說明:公有方法是類的呼叫者和維護者最關心的方法,首屏展示最好;保護方法雖然只是子類關心,也可能是“模板設計模式”下的核心方法;而私有方法外部一般不需要特別關心,是一個黑盒實現;因為承載的資訊價值較低,所有 Service 和 DAO 的 getter/setter 方法放在類體最後。

  • 16.【推薦】setter 方法中,引數名稱與類成員變數名稱一致,this.成員名 = 引數名。在getter/setter 方法中,不要增加業務邏輯,增加排查問題的難度。
    反例:

    	public Integer getData() { 
    	    if (true) { 
    	        return this.data + 100; 
    	    } else {
    	        return this.data - 100;
    	    } 
    	}         
    
  • 17.【推薦】迴圈體內,字串的連線方式,使用 StringBuilder 的 append 方法進行擴充套件。
      說明:反編譯出的位元組碼檔案顯示每次迴圈都會 new 出一個 StringBuilder 物件,然後進行append 操作,最後通過 toString 方法返回 String 物件,造成記憶體資源浪費。
    反例:

		String str = "start"; 
		for (int i = 0; i < 100; i++) { 
		    str = str + "hello"; 
		} 
  • 18.【推薦】final 可以宣告類、成員變數、方法、以及本地變數,下列情況使用 final 關鍵字:
        1) 不允許被繼承的類,如:String 類。
        2) 不允許修改引用的域物件,如:POJO 類的域變數。
        3) 不允許被重寫的方法,如:POJO 類的 setter 方法。
        4) 不允許執行過程中重新賦值的區域性變數。
        5) 避免上下文重複使用一個變數,使用 final 描述可以強制重新定義一個變數,方便更好地進行重構。

  • 【強制】中括號是陣列型別的一部分,陣列定義如下:String[] args;

  • 【強制】POJO類中布林型別的變數,都不要加is,否則部分框架解析會引起序列化錯誤;

  • 【推薦】除常用方法(如 getXxx/isXxx)等外,不要在條件判斷中執行其它複雜的語句,將複雜邏輯判斷的結果賦值給一個有意義的布林變數名,以提高可讀性。
    說明:很多 if 語句內的邏輯相當複雜,閱讀者需要分析條件表示式的最終結果,才能明確什麼樣的條件執行什麼樣的語句,那麼,如果閱讀者分析邏輯表示式錯誤呢?
    正例:// 虛擬碼如下:

		final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
		    if (existed) {
		         ...
		    }     
  • 【強制】在 if/else/for/while/do 語句中必須使用大括號。即使只有一行程式碼,避免採用單行的編碼方式:if (condition) statements;

  • 【推薦】類內方法定義順序依次是:公有方法或保護方法>私有方法>getter/setter方法;
        說明:公有方法是類的呼叫者和維護者最關心的方法,首屏展示最好;保護方法雖然只是子類關心,也可能是“模板設計模式”下的核心方法;而私有方法外部一般不需要特別關心,是一個黑盒實現;因為承載的資訊價值較低,所有 Service 和 DAO 的 getter/setter 方法放在類體最後。



    如需瞭解更多,請看《阿里巴巴Java開發手冊》;