Java編程規(guī)范

本規(guī)范取自《碼出高效—— 阿里巴巴 Java 開發(fā)手冊(cè) 1.4.0》第一章,略有刪減。

一、命名規(guī)范

  1. 代碼中的命名均不能以下劃線或美元符號(hào)開始,也不能以下劃線或美元符號(hào)結(jié)束。

  2. 代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。

    說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式 也要避免采用。

    正例:alibaba / taobao / youku / hangzhou 等國(guó)際通用的名稱,可視同英文。 反例:DaZhePromotion [打折] / getPingfenByName() [評(píng)分] / int 某變量 = 3 
    
  3. 類名使用 UpperCamelCase 風(fēng)格,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID 等。

    正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion 
    反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion 
    
  4. 方法名、參數(shù)名、成員變量、局部變量都統(tǒng)一使用 lowerCamelCase 風(fēng)格,必須遵從 駝峰形式。

    正例: localValue / getHttpMessage() / inputUserId 
    
  5. 常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長(zhǎng)。

    正例:MAX_STOCK_COUNT 
    反例:MAX_COUNT
    
  6. 抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結(jié)尾;測(cè)試類 命名以它要測(cè)試的類的名稱開始,以 Test 結(jié)尾。

  7. 類型與中括號(hào)緊挨相連來表示數(shù)組。

    正例:定義整形數(shù)組 int[] arrayDemo; 
    反例:在 main 參數(shù)中,使用 String args[]來定義。 
    
  8. 包名統(tǒng)一使用小寫,點(diǎn)分隔符之間有且僅有一個(gè)自然語義的英語單詞。包名統(tǒng)一使用 單數(shù)形式,但是類名如果有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式。

    正例:應(yīng)用工具類包名為 com.alibaba.ai.util、類名為 MessageUtils(此規(guī)則參考 spring 的框架結(jié)構(gòu)) 
    
  9. 杜絕完全不規(guī)范的縮寫,避免望文不知義。

    反例:AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類隨 意縮寫嚴(yán)重降低了代碼的可閱讀性。 
    
  10. 為了達(dá)到代碼自解釋的目標(biāo),任何自定義編程元素在命名時(shí),使用盡量完整的單詞 組合來表達(dá)其意。

    正例:在 JDK 中,表達(dá)原子更新的類名為:AtomicReferenceFieldUpdater。 
    反例:變量 int a 的隨意命名方式
    
  11. 各層命名規(guī)約:

    A) Service/DAO 層方法命名規(guī)約    
        1) 獲取單個(gè)對(duì)象的方法用 get 做前綴。   
        2) 獲取多個(gè)對(duì)象的方法用 list 做前綴,復(fù)數(shù)形式結(jié)尾如:listObjects。    
        3) 獲取統(tǒng)計(jì)值的方法用 count 做前綴。    
        4) 插入的方法用 save/insert 做前綴。    
        5) 刪除的方法用 remove/delete 做前綴。    
        6) 修改的方法用 update 做前綴。 
    B) 領(lǐng)域模型命名規(guī)約    
        1) 數(shù)據(jù)對(duì)象:xxxDO,xxx 即為數(shù)據(jù)表名。    
        2) 數(shù)據(jù)傳輸對(duì)象:xxxDTO,xxx 為業(yè)務(wù)領(lǐng)域相關(guān)的名稱。    
        3) 展示對(duì)象:xxxVO,xxx 一般為網(wǎng)頁名稱。    
        4) POJO 是 DO/DTO/BO/VO 的統(tǒng)稱,禁止命名成 xxxPOJO。 
    

二、常量定義

  1. 不允許任何魔法值(即未經(jīng)預(yù)先定義的常量)直接出現(xiàn)在代碼中。

     反例:String key = "Id#taobao_" + tradeId;
         cache.put(key, value); 
    
  2. 在 long 或者 Long 賦值時(shí),數(shù)值后使用大寫的 L,不能是小寫的 l,小寫容易跟數(shù)字 1 混淆,造成誤解。

    說明:Long a = 2l; 寫的是數(shù)字的 21,還是 Long 型的 2? 
    
  3. 不要使用一個(gè)常量類維護(hù)所有常量,要按常量功能進(jìn)行歸類,分開維護(hù)。

    說明:大而全的常量類,雜亂無章,使用查找功能才能定位到修改的常量,不利于理解和維護(hù)。 
    正例:緩存相關(guān)常量放在類 CacheConsts 下;系統(tǒng)配置相關(guān)常量放在類 ConfigConsts 下。 
    
  4. 常量的復(fù)用層次有五層:跨應(yīng)用共享常量、應(yīng)用內(nèi)共享常量、子工程內(nèi)共享常量、包 內(nèi)共享常量、類內(nèi)共享常量。

     1) 跨應(yīng)用共享常量:放置在二方庫中,通常是 client.jar 中的 constant 目錄下。  
     2) 應(yīng)用內(nèi)共享常量:放置在一方庫中,通常是子模塊中的 constant 目錄下。  
         反例:易懂變量也要統(tǒng)一定義成應(yīng)用內(nèi)共享常量,兩位攻城師在兩個(gè)類中分別定義了表示 “是”的變量:     
         類 A 中:public static final String YES = "yes"; 
         類 B 中:public static final String YES = "y";                      A.YES.equals(B.YES),預(yù)期是 true,但實(shí)際返回為 false,導(dǎo)致線上問題。 
     3) 子工程內(nèi)部共享常量:即在當(dāng)前子工程的 constant 目錄下。  
     4) 包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的 constant 目錄下。  
     5) 類內(nèi)共享常量:直接在類內(nèi)部 private static final 定義。 
    

三、代碼格式

  1. 大括號(hào)的使用約定。如果是大括號(hào)內(nèi)為空,則簡(jiǎn)潔地寫成{}即可,不需要換行;如果 是非空代碼塊則:

     1) 左大括號(hào)前不換行。  
     2) 左大括號(hào)后換行。  
     3) 右大括號(hào)前換行。  
     4) 右大括號(hào)后還有 else 等代碼則不換行;表示終止的右大括號(hào)后必須換行
    
  2. 左小括號(hào)和字符之間不出現(xiàn)空格;同樣,右小括號(hào)和字符之間也不出現(xiàn)空格;而左大 括號(hào)前需要空格。詳見第 5 條下方正例提示.

    反例:if (空格 a == b 空格) 
    
  3. if/for/while/switch/do 等保留字與括號(hào)之間都必須加空格。

  4. 任何二目、三目運(yùn)算符的左右兩邊都需要加一個(gè)空格。

    說明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號(hào)等。 
    
  5. 采用 4 個(gè)空格縮進(jìn),禁止使用 tab 字符。

    說明:如果使用 tab 縮進(jìn),必須設(shè)置 1 個(gè) tab 為 4 個(gè)空格。IDEA 設(shè)置 tab 為 4 個(gè)空格時(shí), 請(qǐng)勿勾選 Use tab character;而在 eclipse 中,必須勾選 insert spaces for tabs。

    正例:
    public static void main(String[] args) {      
     
     // 縮進(jìn) 4 個(gè)空格      
        String say = "hello";
     // 運(yùn)算符的左右必須有一個(gè)空格      
        int flag = 0;     
     // 關(guān)鍵詞 if 與括號(hào)之間必須有一個(gè)空格,括號(hào)內(nèi)的 f 與左括號(hào),0 與右括號(hào)不需要空格      
        if (flag == 0) {          
            System.out.println(say);      
        }               
     // 左大括號(hào)前加空格且不換行;左大括號(hào)后換行      
        if (flag == 1) {          
            System.out.println("world");      
            // 右大括號(hào)前換行,右大括號(hào)后有 else,不用換行      
        } else {            
            System.out.println("ok");      
            // 在右大括號(hào)后直接結(jié)束,則必須換行      
        }  
    } 
    
  6. 注釋的雙斜線與注釋內(nèi)容之間有且僅有一個(gè)空格。

    正例:  
     // 這是示例注釋,請(qǐng)注意在雙斜線之后有一個(gè)空格  
     String ygb = new String(); 
    
  7. 單行字符數(shù)限制不超過 120 個(gè),超出需要換行,換行時(shí)遵循如下原則:

    1) 第二行相對(duì)第一行縮進(jìn) 4 個(gè)空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。  
    2) 運(yùn)算符與下文一起換行。  
    3) 方法調(diào)用的點(diǎn)符號(hào)與下文一起換行。  
    4) 方法調(diào)用中的多個(gè)參數(shù)需要換行時(shí),在逗號(hào)后進(jìn)行。  
    5) 在括號(hào)前不要換行,見反例。
    
    正例: 
     StringBuffer sb = new StringBuffer();  
    // 超過 120 個(gè)字符的情況下,換行縮進(jìn) 4 個(gè)空格,點(diǎn)號(hào)和方法名稱一起換行         sb.append("zi").append("xin")...    
         .append("huang")...
         .append("huang")... 
         .append("huang");  
    反例: 
     StringBuffer sb = new StringBuffer();  
    // 超過 120 個(gè)字符的情況下,不要在括號(hào)前換行                               sb.append("zi").append("xin")...append     
         ("huang");   
     
    // 參數(shù)很多的方法調(diào)用可能超過 120 個(gè)字符,不要在逗號(hào)前換行  
     method(args1, args2, args3, ...      
         , argsX); 
    
  8. 方法參數(shù)在定義和傳入時(shí),多個(gè)參數(shù)逗號(hào)后邊必須加空格。

    正例:下例中實(shí)參的 args1,后邊必須要有一個(gè)空格。 
     method(args1, args2, args3); 
    
  9. IDE 的 text file encoding 設(shè)置為 UTF-8; IDE 中文件的換行符使用 Unix 格式, 不要使用 Windows 格式。

  10. 單個(gè)方法的總行數(shù)不超過 80 行。

    說明:包括方法簽名、結(jié)束右大括號(hào)、方法內(nèi)代碼、注釋、空行、回車及任何不可見字符的總 行數(shù)不超過 80 行。 
    正例:代碼邏輯分清紅花和綠葉,個(gè)性和共性,綠葉邏輯單獨(dú)出來成為額外方法,使主干代碼 更加清晰;共性邏輯抽取成為共性方法,便于復(fù)用和維護(hù)。
    
  11. 沒有必要增加若干空格來使某一行的字符與上一行對(duì)應(yīng)位置的字符對(duì)齊。

    正例: 
        int one = 1;
        long two = 2L;  
        float three = 3F;
        StringBuffer sb = new StringBuffer();  
    說明:增加 sb 這個(gè)變量,如果需要對(duì)齊,則給 a、b、c 都要增加幾個(gè)空格,在變量比較多的 情況下,是非常累贅的事情。 
    
  12. 不同邏輯、不同語義、不同業(yè)務(wù)的代碼之間插入一個(gè)空行分隔開來以提升可讀性。

    說明:任何情形,沒有必要插入多個(gè)空行進(jìn)行隔開。

四、OOP規(guī)約

OOP ——面向?qū)ο蟪绦蛟O(shè)計(jì)(Object Oriented Programming)

  1. 避免通過一個(gè)類的對(duì)象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析成 本,直接用類名來訪問即可

  2. 所有的覆寫方法,必須加@Override 注解。

    說明:getObject()與 get0bject()的問題。一個(gè)是字母的 O,一個(gè)是數(shù)字的 0,加@Override 可以準(zhǔn)確判斷是否覆蓋成功。另外,如果在抽象類中對(duì)方法簽名進(jìn)行修改,其實(shí)現(xiàn)類會(huì)馬上編 譯報(bào)錯(cuò)。

  3. 相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用 Java 的可變參數(shù),避免使用 Object。

  說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用可變參數(shù)編程) 
   正例:public List<User> listUsers(String type, Long... ids) {...} 
  1. 外部正在調(diào)用或者二方庫依賴的接口,不允許修改方法簽名,避免對(duì)接口調(diào)用方產(chǎn)生 影響。接口過時(shí)必須加@Deprecated 注解,并清晰地說明采用的新接口或者新服務(wù)是什么。

  2. 不能使用過時(shí)的類或方法

   說明:java.net.URLDecoder 中的方法 decode(String encodeStr) 這個(gè)方法已經(jīng)過時(shí),應(yīng)該使用雙參數(shù) decode(String source, String encode)。接口提供方既然明確是過時(shí)接口, 那么有義務(wù)同時(shí)提供新的接口;作為調(diào)用方來說,有義務(wù)去考證過時(shí)方法的新實(shí)現(xiàn)是什么。
  1. Object 的 equals 方法容易拋空指針異常,應(yīng)使用常量或確定有值的對(duì)象來調(diào)用 equals。

    正例:"test".equals(object); 
    反例:object.equals("test"); 
    說明:推薦使用 java.util.Objects#equals(JDK7 引入的工具類) 
    
  2. 所有的相同類型的包裝類對(duì)象之間值的比較,全部使用 equals 方法比較。
    說明:對(duì)于 Integer var = ? 在-128 至 127 范圍內(nèi)的賦值,Integer 對(duì)象是在 IntegerCache.cache 產(chǎn)生,會(huì)復(fù)用已有對(duì)象,這個(gè)區(qū)間內(nèi)的 Integer 值可以直接使用==進(jìn)行 判斷,但是這個(gè)區(qū)間之外的所有數(shù)據(jù),都會(huì)在堆上產(chǎn)生,并不會(huì)復(fù)用已有對(duì)象,這是一個(gè)大坑, 推薦使用 equals 方法進(jìn)行判斷。

  3. 關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:

     1) 【強(qiáng)制】所有的 POJO 類屬性必須使用包裝數(shù)據(jù)類型。  
     2) 【強(qiáng)制】RPC 方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。  
     3) 【推薦】所有的局部變量使用基本數(shù)據(jù)類型。  
     說明:POJO 類屬性沒有初值是提醒使用者在需要使用時(shí),必須自己顯式地進(jìn)行賦值,任何 NPE 問題,或者入庫檢查,都由使用者來保證。
    
    正例:數(shù)據(jù)庫的查詢結(jié)果可能是 null,因?yàn)樽詣?dòng)拆箱,用基本數(shù)據(jù)類型接收有 NPE 風(fēng)險(xiǎn)。  
    反例:比如顯示成交總額漲跌情況,即正負(fù) x%,x 為基本數(shù)據(jù)類型,調(diào)用的 RPC 服務(wù),調(diào)用 不成功時(shí),返回的是默認(rèn)值,頁面顯示為 0%,這是不合理的,應(yīng)該顯示成中劃線。所以包裝 數(shù)據(jù)類型的 null 值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出。 
    
  4. 構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯,如果有初始化邏輯,請(qǐng)放在 init 方法中。

  5. 使用索引訪問用 String 的 split 方法得到的數(shù)組時(shí),需做最后一個(gè)分隔符后有無 內(nèi)容的檢查,否則會(huì)有拋 IndexOutOfBoundsException 的風(fēng)險(xiǎn)。

    說明: 
        String str = "a,b,c,,";  
        String[] ary = str.split(",");  
        // 預(yù)期大于 3,結(jié)果是 3 
        System.out.println(ary.length);
    
  6. 當(dāng)一個(gè)類有多個(gè)構(gòu)造方法,或者多個(gè)同名方法,這些方法應(yīng)該按順序放置在一起, 便于閱讀.

    類內(nèi)方法定義的順序依次是:公有方法或保護(hù)方法 > 私有方法 > getter/setter 方法。

    說明:公有方法是類的調(diào)用者和維護(hù)者最關(guān)心的方法,首屏展示最好;保護(hù)方法雖然只是子類 關(guān)心,也可能是“模板設(shè)計(jì)模式”下的核心方法;而私有方法外部一般不需要特別關(guān)心,是一個(gè) 黑盒實(shí)現(xiàn);因?yàn)槌休d的信息價(jià)值較低,所有 Service 和 DAO 的 getter/setter 方法放在類體 最后。

  7. setter 方法中,參數(shù)名稱與類成員變量名稱一致,this.成員名 = 參數(shù)名。在 getter/setter 方法中,不要增加業(yè)務(wù)邏輯,增加排查問題的難度。

    反例: 
       public Integer getData() {      
        if (condition) {  
            return this.data + 100;  
        } else { 
            return this.data - 100; 
        }  
    }
    
  1. 循環(huán)體內(nèi),字符串的連接方式,使用 StringBuilder 的 append 方法進(jìn)行擴(kuò)展。

    說明:下例中,反編譯出的字節(jié)碼文件顯示每次循環(huán)都會(huì) new 出一個(gè) StringBuilder 對(duì)象, 然后進(jìn)行 append 操作,最后通過 toString 方法返回 String 對(duì)象,造成內(nèi)存資源浪費(fèi)。 
    反例: 
        String str = "start";      
        for (int i = 0; i < 100; i++) {          
            str = str + "hello";      
        } 
    
    
    
  2. final 可以聲明類、成員變量、方法、以及本地變量,下列情況使用 final 關(guān)鍵字。

     1) 不允許被繼承的類,如:String 類。  
     2) 不允許修改引用的域?qū)ο蟆? 
     3) 不允許被重寫的方法,如:POJO 類的 setter 方法。
     4) 不允許運(yùn)行過程中重新賦值的局部變量。  
     5) 避免上下文重復(fù)使用一個(gè)變量,使用 final 描述可以強(qiáng)制重新定義一個(gè)變量,方便更好 地進(jìn)行重構(gòu).
    
  3. 慎用 Object 的 clone 方法來拷貝對(duì)象。

    說明:對(duì)象的 clone 方法默認(rèn)是淺拷貝,若想實(shí)現(xiàn)深拷貝需要重寫 clone 方法實(shí)現(xiàn)域?qū)ο蟮?深度遍歷式拷貝。

  4. 類成員與方法訪問控制從嚴(yán):

    1) 如果不允許外部直接通過 new 來創(chuàng)建對(duì)象,那么構(gòu)造方法必須是 private。  
    2) 工具類不允許有 public 或 default 構(gòu)造方法。  
    3) 類非 static 成員變量并且與子類共享,必須是 protected。   
    4) 類非 static 成員變量并且僅在本類使用,必須是 private。  
    5) 類 static 成員變量如果僅在本類使用,必須是 private。  
    6) 若是 static 成員變量,考慮是否為 final。  
    7) 類成員方法只供類內(nèi)部調(diào)用,必須是 private。   
    8) 類成員方法只對(duì)繼承類公開,那么限制為 protected。 
    說明:任何類、方法、參數(shù)、變量,嚴(yán)控訪問范圍。過于寬泛的訪問范圍,不利于模塊解耦。 思考:如果是一個(gè) private 的方法,想刪除就刪除,可是一個(gè) public 的 service 成員方法或
    成員變量,刪除一下,不得手心冒點(diǎn)汗嗎?變量像自己的小孩,盡量在自己的視線內(nèi),變量作 用域太大,無限制的到處跑,那么你會(huì)擔(dān)心的。 
    

五、控制語句

  1. 在一個(gè) switch 塊內(nèi),每個(gè) case 要么通過 break/return 等來終止,要么注釋說明程 序?qū)⒗^續(xù)執(zhí)行到哪一個(gè) case 為止;在一個(gè) switch 塊內(nèi),都必須包含一個(gè) default 語句并且 放在最后,即使空代碼。

  2. 在 if/else/for/while/do 語句中必須使用大括號(hào)。即使只有一行代碼,避免采用 單行的編碼方式:if (condition) statements;

  3. 在高并發(fā)場(chǎng)景中,避免使用”等于”判斷作為中斷或退出的條件。

    說明:如果并發(fā)控制沒有處理好,容易產(chǎn)生等值判斷被“擊穿”的情況,使用大于或小于的區(qū)間 判斷條件來代替。 
    反例:判斷剩余獎(jiǎng)品數(shù)量等于 0 時(shí),終止發(fā)放獎(jiǎng)品,但因?yàn)椴l(fā)處理錯(cuò)誤導(dǎo)致獎(jiǎng)品數(shù)量瞬間變 成了負(fù)數(shù),這樣的話,活動(dòng)無法終止。
    
  4. 表達(dá)異常的分支時(shí),少用 if-else 方式,這種方式可以改寫成:

    if (condition) {              
        ...             
        return obj;    
    }   // 接著寫 else 的業(yè)務(wù)邏輯代碼;  
    說明:如果非得使用 if()...else if()...else...方式表達(dá)邏輯,避免后續(xù)代碼維 護(hù)困難,請(qǐng)勿超過 3 層。  
    正例:超過 3 層的 if-else 的邏輯判斷代碼可以使用衛(wèi)語句、策略模式、狀態(tài)模式等來實(shí)現(xiàn), 其中衛(wèi)語句示例如下: 
     public void today() {      
         if (isBusy()) {   
                System.out.println(“change time.”);            
                return;      
            } 
     
             if (isFree()) {  
                 System.out.println(“go to travel.”);                            
                return;     
            } 
     
         System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);                return; 
     }
    
  5. 除常用方法(如 getXxx/isXxx)等外,不要在條件判斷中執(zhí)行其它復(fù)雜的語句,將 復(fù)雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。

    說明:很多 if 語句內(nèi)的邏輯相當(dāng)復(fù)雜,閱讀者需要分析條件表達(dá)式的最終結(jié)果,才能明確什么 樣的條件執(zhí)行什么樣的語句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢? 
    正例: 
        // 偽代碼如下 
        final boolean existed = (file.open(fileName, "w") != null) && (...) || (...); 
     if (existed) {     
            ... 
        }   
    反例: 
        if ((file.open(fileName, "w") != null) && (...) || (...)) {     
            ... 
        } 
    
  6. 循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理,如定義對(duì)象、變量、 獲取數(shù)據(jù)庫連接,進(jìn)行不必要的 try-catch 操作(這個(gè) try-catch 是否可以移至循環(huán)體外)。

  7. 避免采用取反邏輯運(yùn)算符。

     說明:取反邏輯不利于快速理解,并且取反邏輯寫法必然存在對(duì)應(yīng)的正向邏輯寫法。 
     正例:使用 if (x < 628) 來表達(dá) x 小于 628。 
     反例:使用 if (!(x >= 628)) 來表達(dá) x 小于 628。
    

六、注釋規(guī)約

  1. 類、類屬性、類方法的注釋必須使用 Javadoc 規(guī)范,使用/**內(nèi)容*/格式,不得使用 // xxx 方式。

    說明:在 IDE 編輯窗口中,Javadoc 方式會(huì)提示相關(guān)注釋,生成 Javadoc 可以正確輸出相應(yīng)注 釋;在 IDE 中,工程調(diào)用方法時(shí),不進(jìn)入方法即可懸浮提示方法、參數(shù)、返回值的意義,提高 閱讀效率。 
    
  2. 所有的抽象方法(包括接口中的方法)必須要用 Javadoc 注釋、除了返回值、參數(shù)、 異常說明外,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能。

    說明:對(duì)子類的實(shí)現(xiàn)要求,或者調(diào)用注意事項(xiàng),請(qǐng)一并說明。 
    
  3. 所有的類都必須添加創(chuàng)建者和創(chuàng)建日期。

  4. 方法內(nèi)部單行注釋,在被注釋語句上方另起一行,使用//注釋。方法內(nèi)部多行注釋 使用/* */注釋,注意與代碼對(duì)齊。

  5. 所有的枚舉類型字段必須要有注釋,說明每個(gè)數(shù)據(jù)項(xiàng)的用途。

  6. 與其“半吊子”英文來注釋,不如用中文注釋把問題說清楚。專有名詞與關(guān)鍵字保持 英文原文即可。

  7. 代碼修改的同時(shí),注釋也要進(jìn)行相應(yīng)的修改,尤其是參數(shù)、返回值、異常、核心邏輯 等的修改。

    說明:代碼與注釋更新不同步,就像路網(wǎng)與導(dǎo)航軟件更新不同步一樣,如果導(dǎo)航軟件嚴(yán)重滯后, 就失去了導(dǎo)航的意義。 
    
  8. 謹(jǐn)慎注釋掉代碼。在上方詳細(xì)說明,而不是簡(jiǎn)單地注釋掉。如果無用,則刪除。

    說明:代碼被注釋掉有兩種可能性:1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。2)永久不用。前者如果沒 有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉庫保存了歷史代碼)。 
    
  9. 對(duì)于注釋的要求:第一、能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯;第二、能夠描述業(yè)務(wù)含 義,使別的程序員能夠迅速了解到代碼背后的信息。完全沒有注釋的大段代碼對(duì)于閱讀者形同天書,注釋是給自己看的,即使隔很長(zhǎng)時(shí)間,也能清晰理解當(dāng)時(shí)的思路;注釋也是給繼任者看 的,使其能夠快速接替自己的工作。

  10. 好的命名、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡(jiǎn)準(zhǔn)確、表達(dá)到位。避免出現(xiàn)注釋的 一個(gè)極端:過多過濫的注釋,代碼的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。

    反例: 
    // put elephant into fridge  
        put(elephant, fridge);      
    方法名 put,加上兩個(gè)有意義的變量名 elephant 和 fridge,已經(jīng)說明了這是在干什么,語 義清晰的代碼不需要額外的注釋。
    
  11. 特殊注釋標(biāo)記,請(qǐng)注明標(biāo)記人與標(biāo)記時(shí)間。注意及時(shí)處理這些標(biāo)記,通過標(biāo)記掃描, 經(jīng)常清理此類標(biāo)記。線上故障有時(shí)候就是來源于這些標(biāo)記處的代碼。

     1) 待辦事宜(TODO):( 標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])    
        表示需要實(shí)現(xiàn),但目前還未實(shí)現(xiàn)的功能。這實(shí)際上是一個(gè) Javadoc 的標(biāo)簽,目前的 Javadoc 還沒有實(shí)現(xiàn),但已經(jīng)被廣泛使用。只能應(yīng)用于類,接口和方法(因?yàn)樗且粋€(gè) Javadoc 標(biāo)簽)。  
     2) 錯(cuò)誤,不能工作(FIXME):(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])    
        在注釋中用 FIXME 標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。
    

七、其他

  1. 在使用正則表達(dá)式時(shí),利用好其預(yù)編譯功能,可以有效加快正則匹配速度。

    說明:不要在方法體內(nèi)定義:Pattern pattern = Pattern.compile(“規(guī)則”); 
    
  2. 后臺(tái)輸送給頁面的變量必須加$!{var}——中間的感嘆號(hào).

    說明:如果 var 等于 null 或者不存在,那么${var}會(huì)直接顯示在頁面上。 
    
  3. 注意 Math.random() 這個(gè)方法返回是 double 類型,注意取值的范圍 0≤x<1(能夠 取到零值,注意除零異常),如果想獲取整數(shù)類型的隨機(jī)數(shù),不要將 x 放大 10 的若干倍然后 取整,直接使用 Random 對(duì)象的 nextInt 或者 nextLong 方法。

  4. 獲取當(dāng)前毫秒數(shù) System.currentTimeMillis(); 而不是 new Date().getTime();

    說明:如果想獲取更加精確的納秒級(jí)時(shí)間值,使用 System.nanoTime()的方式。在 JDK8 中, 針對(duì)統(tǒng)計(jì)時(shí)間等場(chǎng)景,推薦使用 Instant 類。
    
  5. 不要在視圖模板中加入任何復(fù)雜的邏輯。

    說明:根據(jù) MVC 理論,視圖的職責(zé)是展示,不要搶模型和控制器的活。 
    
  6. 任何數(shù)據(jù)結(jié)構(gòu)的構(gòu)造或初始化,都應(yīng)指定大小,避免數(shù)據(jù)結(jié)構(gòu)無限增長(zhǎng)吃光內(nèi)存。

  7. 及時(shí)清理不再使用的代碼段或配置信息。

    說明:對(duì)于垃圾代碼或過時(shí)配置,堅(jiān)決清理干凈,避免程序過度臃腫,代碼冗余。 
    正例:對(duì)于暫時(shí)被注釋掉,后續(xù)可能恢復(fù)使用的代碼片斷,在注釋代碼上方,統(tǒng)一規(guī)定使用三 個(gè)斜杠(///)來說明注釋掉代碼的理由
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容