天天看點

Java研發規約

Java研發規約

目錄

​​Java研發規約 1​​

​​一、命名風格 1​​

​​二、常量定義 4​​

​​三、代碼格式 5​​

​​四、OOP規約 7​​

​​五、日期時間 10​​

​​六、集合處理 11​​

​​七、并發處理 13​​

​​八、控制語句 16​​

​​九、注釋規約 17​​

​​十、其他 19​​

命名風格​

  1. 【強制】代碼中的命名均不能以下劃線或美元符号開始,也不能以下劃線 或美元符号結束。 反例:_name / __name / $name / name_ / name$ / name__​
  2. 【強制】所有程式設計相關的命名嚴禁使用拼音與英文混合的方式,更不允許 直接使用中文的方式。 說明:正确的英文拼寫和文法可以讓閱讀者易于了解,避免歧義。注意, 純拼音命名方式更要避免采用。​

    正例:ali / alibaba / taobao / cainiao/ aliyun/ youku / hangzhou 等 國際通用的名稱,可視同英文。​

    反例:DaZhePromotion [打折] / getPingfenByName() [評分] / ​

    String fw[福娃] / int 某變量 = 3​

  3. 【強制】類名使用 UpperCamelCase 風格,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID 等。 正例:ForceCode / UserDO / HtmlDTO / XmlService / TcpUdpDeal / TaPromotion​

    反例:forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion​

  4. 【強制】方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格。 正例: localValue / getHttpMessage() / inputUserId​
  5. 【強制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清 楚,不要嫌名字長。 正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME​

    反例:MAX_COUNT / EXPIRED_TIME​

  6. 【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類命名以它要測試的類的名稱開始,以 Test 結 尾。
  7. 【強制】類型與中括号緊挨相連來表示數組。 正例:定義整形數組 int[] arrayDemo。​

    反例:在 main 參數中,使用 String args[]來定義。​

  8. 【強制】包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語 單詞。包名統一使用單數形式,但是類名如果有複數含義,類名可以使 用複數形式。 正例:應用工具類包名為 com.alibaba.ei.kunlun.aap.util、類名為 MessageUtils(此規則參考 spring 的架構結構)​
  9. 【強制】避免在子父類的成員變量之間、或者不同代碼塊的局部變量之間 采用完全相同的命名,使可了解性降低。 說明:子類、父類成員變量名相同,即使是 public 類型的變量也能夠 通過編譯,另外,局部變量在同一方法内的不同代碼塊中同名也是合法 的,這些情況都要避免。對于非 setter/getter 的參數名稱也要避免與 成員變量名稱相同。​
  10. 【強制】杜絕完全不規範的縮寫,避免望文不知義。 反例:AbstractClass“縮寫”成 AbsClass;condition“縮寫”成 condi;Function 縮寫”成 Fu,此類随意縮寫嚴重降低了代碼的可閱 讀性。​
  11. 【推薦】接口類中的方法和屬性不要加任何修飾符号(public 也不要加), 保持代碼的簡潔性,并加上有效的 Javadoc 注釋。盡量不要在接口裡 定義變量,如果一定要定義變量,确定與接口方法相關,并且是整個應 用的基礎常量。 正例:接口方法簽名 void commit();接口基礎常量 String COMPANY = "alibaba";​

    反例:接口方法定義 public abstract void f();​

    說明:JDK8 中接口允許有預設實作,那麼這個 default 方法,是對所 有實作類都有價值的預設實作。​

  12. 接口和實作類的命名有兩套規則: 1)【強制】對于 Service 和 DAO 類,基于 SOA 的理念,暴露出來 的服務一定是接口,内部的實作類用 Impl 的字尾與接口差別。​

    正例:CacheServiceImpl 實作 CacheService 接口。​

    2)【推薦】如果是形容能力的接口名稱,取對應的形容詞為接口名(通 常是–able 的形容詞)。​

    正例:AbstractTranslator 實作 Translatable 接口。​

  13. 【參考】枚舉類名帶上 Enum 字尾,枚舉成員名稱需要全大寫,單詞 間用下劃線隔開。

說明:枚舉其實就是特殊的常量類,且構造方法被預設強制是私有。

正例:枚舉名字為 ProcessStatusEnum 的成員名稱:SUCCESS / UNKNOWN_REASON。

常量定義​

  1. 【強制】不允許任何魔法值(即未經預先定義的常量)直接出現在代碼 反例:String key = "Id#taobao_" + tradeId;
  2. 【強制】在 long 或者 Long 指派時,數值後使用大寫字母 L,不能是 小寫字母 l,小寫容易跟數字混淆,造成誤解。 說明:Long a = 2l; 寫的是數字的 21,還是 Long 型的 2?​
  3. 【推薦】不要使用一個常量類維護所有常量,要按常量功能進行歸類,分開維護。說明:大而全的常量類,雜亂無章,使用查找功能才能定位到修改的常量,不利于了解,也不利于維護。

    正例:緩存相關常量放在類 CacheConsts 下;系統配置相關常量放在類 SystemConfigConsts 下

代碼格式​

  1. 【強制】如果是大括号内為空,則簡潔地寫成{}即可,大括号中間無需換 行和空格;如果是非空代碼塊則: 1) 左大括号前不換行。​

    2) 左大括号後換行。​

    3) 右大括号前換行。​

    4)右大括号後還有 else 等代碼則不換行;表示終止的右大括号後必 須換行。​

  2. 【強制】if/for/while/switch/do 等保留字與括号之間都必須加空格。
  3. 【強制】左小括号和右邊相鄰字元之間不出現空格;右小括号和左邊相 鄰字元之間也不出現空格;而左大括号前需要加空格。 反例:if (空格 a == b 空格)​
  4. 【強制】任何二目、三目運算符的左右兩邊都需要加一個空格。 說明:包括指派運算符=、邏輯運算符&&、加減乘除符号等。​
  5. 【強制】采用 4 個空格縮進,禁止使用 Tab 字元。 說明:如果使用 Tab 縮進,必須設定 1 個 Tab 為 4 個空格。IDEA 設 置 Tab 為 4 個空格時,請勿勾選 Use tab character;而在 Eclipse 中,必須勾選 insert spaces for tabs。​
  6. 【強制】注釋的雙斜線與注釋内容之間有且僅有一個空格。
  7. 【強制】在進行類型強制轉換時,右括号與強制轉換值之間不需要任何空 格隔開。 正例:​

    double first = 3.2d;​

    int second = (int)first + 2;​

  8. 【強制】方法參數在定義和傳入時,多個參數逗号後面必須加空格。 正例:下例中實參的 args1,後邊必須要有一個空格。​

    method(args1, args2, args3);​

  9. 【強制】IDE 的 text file encoding 設定為 UTF-8; IDE 中檔案的換行 符使用 Unix 格式,不要使用 Windows 格式。
  10. 【推薦】不同邏輯、不同語義、不同業務的代碼之間插入一個空行分隔 開來以提升可讀性。 說明:任何情形,沒有必要插入多個空行進行隔開。​
  11. 【推薦】單個方法的總行數不超過 80 行。

說明:除注釋之外的方法簽名、左右大括号、方法内代碼、空行、回車 及任何不可見字元的總行數不超過行。

正例:代碼邏輯厘清紅花和綠葉,個性和共性,綠葉邏輯單獨出來成為 額外方法,使主幹代碼更加清晰;共性邏輯抽取成為共性方法,便于複 用和維護。

OOP規約​

  1. 【強制】所有的覆寫方法,必須加@Override 注解。 說明:getObject()與 get0bject()的問題。一個是字母的 O,一個是 數字的 0,加@Override 可以準确判斷是否覆寫成功。另外,如果在 抽象類中對方法簽名進行修改,其實作類會馬上編譯報錯。​
  2. 【強制】Object 的 equals 方法容易抛空指針異常,應使用常量或确定 有值的對象來調用 equals。 正例:"test".equals(object);​

    反例:object.equals("test");​

    說明:推薦使用 JDK7 引入的工具類 java.util.Objects#equals(Object a, Object b)​

  3. 【強制】如上所示 BigDecimal 的等值比較應使用 compareTo()方法, 而不是 equals()方法。 說明:equals()方法會比較值和精度(1.0 與 1.00 傳回結果為 false), 而 compareTo()則會忽略精度。​
  4. 【強制】定義資料對象 DO 類時,屬性類型要與資料庫字段類型相比對。 正例:資料庫字段的 bigint 必須與類屬性的 Long 類型相對應。​

    反例:某個案例的資料庫表 id 字段定義類型 bigint unsigned,實際 類對象屬性為 Integer,随着 id 越來越大,超過 Integer 的表示範圍 而溢出成為負數。​

  5. 【強制】禁止使用構造方法 BigDecimal(double)的方式把 double 值 轉化為 BigDecimal 對象。說明:BigDecimal(double)存在精度損失 風險,在精确計算或值比較的場景中可能會導緻業務邏輯異常。如: BigDecimal g = new BigDecimal(0.1F); 實際的存儲值為: 0.10000000149 正例:優先推薦入參為 String 的構造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其實執行了Double 的 toString,而 Double 的 toString 按 double 的實際能表達的精度對尾數進行了 截斷。​

    BigDecimal recommend1 = new BigDecimal("0.1");​

    BigDecimal recommend2 = BigDecimal.valueOf(0.1);​

  6. 【強制】序列化類新增屬性時,請不要修改 serialVersionUID 字段,避 免反序列失敗;如果完全不相容更新,避免反序列化混亂,那麼請修改 serialVersionUID 值。 說明:注意 serialVersionUID 不一緻會抛出序列化運作時異常。​
  7. 【強制】禁止在 POJO 類中,同時存在對應屬性 xxx 的 isXxx()和 getXxx()方法。 說明:架構在調用屬性 xxx 的提取方法時,并不能确定哪個方法一定是 被優先調用到的。​
  8. 【推薦】使用索引通路用 String 的 split 方法得到的數組時,需做最後 一個分隔符後有無内容的檢查,否則會有抛 IndexOutOfBoundsException 的風險。 說明:​

    String str = "a,b,c,,";​

    String[] ary = str.split(",");​

    // 預期大于 3,結果是 3​

    System.out.println(ary.length);​

  9. 【推薦】當一個類有多個構造方法,或者多個同名方法,這些方法應該按 順序放置在一起,便于閱讀,此條規則優先于下一條。
  10. 【推薦】循環體内,字元串的連接配接方式,使用 StringBuilder 的 append 方法進行擴充。

說明:下例中,反編譯出的位元組碼檔案顯示每次循環都會 new 出一個 StringBuilder 對象,然後進行 append 操作,最後通過 toString 方 法傳回 String 對象,造成記憶體資源浪費。

反例:

String str = "start";

for (int i = 0; i < 100; i++) {

str = str + "hello";

}

日期時間​

  1. 【強制】日期格式化時,傳入 pattern 中表示年份統一使用小寫的 y。 說明:日期格式化時,yyyy 表示當天所在的年,而大寫的 YYYY 代表 是 week in which year(JDK7 之後引入的概念),意思是當天所在的 周屬于的年份,一周從周日開始,周六結束,隻要本周跨年,傳回的 YYYY 就是下一年。​

    正例:表示日期和時間的格式如下所示:​

    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")​

  2. 【強制】在日期格式中厘清楚大寫的 M 和小寫的 m,大寫的 H 和小寫的 h 分别指代的意義。說明:日期格式中的這兩對字母表意如下:

    1) 表示月份是大寫的 M;

    2) 表示分鐘則是小寫的 m;

    3) 24 小時制的是大寫的 H;

    4) 12 小時制的則是小寫的 h。

    3.【強制】擷取目前毫秒數:System.currentTimeMillis(); 而不是 new Date().getTime()。

    4.【強制】不允許在程式任何地方中使用:

    1)java.sql.Date。 2)java.sql.Time。3)java.sql.Timestamp。

    說明:第 1 個不記錄時間,getHours()抛出異常;第 2 個不記錄日期,getYear()抛出異常;第 3 個在構造方法 super((time/1000)*1000),在 Timestamp 屬性 fastTime 和 nanos 分别存儲秒和納秒資訊。

    5.【強制】不要在程式中寫死一年為 365 天,避免在公曆閏年時出現日期轉換錯誤或程式邏輯錯誤。

    正例:

    // 擷取今年的天數

    int daysOfThisYear = LocalDate.now().lengthOfYear();

    // 擷取指定某年的天數

    LocalDate.of(2021, 1, 1).lengthOfYear();

集合處理​

  1. 【強制】關于 hashCode 和 equals 的處理,遵循如下規則:​
  2. 1) 隻要覆寫 equals,就必須覆寫 hashCode。​

    2) 因為 Set 存儲的是不重複的對象,依據 hashCode 和 equals 進 行判斷,是以 Set 存儲的對象必須覆寫這兩種方法。​

    3)如果自定義對象作為 Map 的鍵,那麼必須覆寫 hashCode 和 equals。​

    說明:String 因為覆寫了 hashCode 和 equals 方法,是以可以愉 快地将 String 對象作為 key 來使用。​

  3. 【強制】判斷所有集合内部的元素是否為空,使用 isEmpty()方法,而不 是 size()==0 的方式。​
  4. 說明:在某些集合中,前者的時間複雜度為 O(1),而且可讀性更好。​
  5. 【強制】在使用 java.util.stream.Collectors 類的 toMap()方法轉為 Map 集合時,一定要注意當 value 為 null 時會抛 NPE 異常。​
  6. 說明:在 java.util.HashMap 的 merge 方法裡會進行如下的判斷:​

    if (value == null || remappingFunction == null)​

    throw new NullPointerException();​

  7. 【強制】使用 Map 的方法 keySet()/values()/entrySet()傳回集合對象 時,不可以對其進行添加元素操作,否則會抛出 UnsupportedOperationException 異常。​
  8. 【強制】使用集合轉數組的方法,必須使用集合的 toArray(T[] array), 傳入的是類型完全一緻、長度為 0 的空數組。​
  9. 反例:直接使用 toArray 無參方法存在問題,此方法傳回值隻能是 Object[]類,若強轉其它類型數組将出現 ClassCastException 錯誤。​
  10. 【強制】在使用 Collection 接口任何實作類的 addAll()方法時,都要 對輸入的集合參數進行 NPE 判斷。​
  11. 說明:在 ArrayList#addAll 方法的第一行代碼即 Object[] a = c.toArray(); 其中 c 為輸入集合參數,如果為 null,則直接抛出異常。​
  12. 【強制】不要在 foreach 循環裡進行元素的 remove/add 操作。 remove 元素請使用 Iterator 方式,如果并發操作,需要對 Iterator 對象加鎖。​
  13. 正例:​

    List<String> list = new ArrayList<>();​

    list.add("1");​

    list.add("2");​

    Iterator<String> iterator = list.iterator();​

    while (iterator.hasNext()) {​

    String item = iterator.next();​

    if (删除元素的條件) {​

    iterator.remove();​

    }​

    }​

  14. 【推薦】集合初始化時,指定集合初始值大小。​
  15. 說明:HashMap 使用 HashMap(int initialCapacity) 初始化,如果暫 時無法确定集合大小,那麼指定預設值(16)即可。​
  16. 【參考】利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作, 避免使用 List 的contains()進行周遊去重或者判斷包含操作。​

并發處理​

1. 【強制】擷取單例對象需要保證線程安全,其中的方法也要保證線 程安全。​

說明:資源驅動類、工具類、單例工廠類都需要注意。​

2. 【強制】線程資源必須通過線程池提供,不允許在應用中自行顯式建立 線程。​

說明:線程池的好處是減少在建立和銷毀線程上所消耗的時間以及系統 資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系 統建立大量同類線程而導緻消耗完記憶體或者“過度切換”的問題。​

  1. 【強制】建立線程或線程池時請指定有意義的線程名稱,友善出錯時回溯。
  2. 【強制】線程池不允許使用 Executors 去建立,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明确線 程池的運作規則,規避資源耗盡的風險。 說明:Executors 傳回的線程池對象的弊端如下:​

    1) FixedThreadPool 和 SingleThreadPool:​

    允許的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求 2) CachedThreadPool:​

    允許的建立線程數量為 Integer.MAX_VALUE,可能會建立大量的線程​

  3. 【強制】必須回收自定義的 ThreadLocal 變量,尤其線上程池場景下, 線程經常會被複用,如果不清理自定義的 ThreadLocal 變量,可能會 影響後續業務邏輯和造成記憶體洩露等問題。盡量在代理中使用 try-finally 塊進行回收。
  4. 【強制】高并發時,同步調用應該去考量鎖的性能損耗。能用無鎖資料結 構,就不要用鎖;能鎖區塊,就不要鎖整個方法體;能用對象鎖,就不 要用類鎖。 說明:盡可能使加鎖的代碼塊工作量盡可能的小,避免在鎖代碼塊中調 用 RPC 方法。​
  5. 【強制】對多個資源、資料庫表、對象同時加鎖時,需要保持一緻的加鎖 順序,否則可能會造成死鎖。 說明:線程一需要對表 A、B、C 依次全部加鎖後才可以進行更新操作, 那麼線程二的加鎖順序也必須是 A、B、C,否則可能出現死鎖。​
  6. 【強制】在使用阻塞等待擷取鎖的方式中,必須在 try 代碼塊之外,并 且在加鎖方法與 try 代碼塊之間沒有任何可能抛出異常的方法調用,避 免加鎖成功後,在 finally 中無法解鎖。 說明一:如果在 lock 方法與 try 代碼塊之間的方法調用抛出異常,那 麼無法解鎖,造成其它線程無法成功擷取鎖。​

    說明二:如果 lock 方法在 try 代碼塊之内,可能由于其它方法抛出異 常,導緻在 finally 代碼塊中,unlock對未加鎖的對象解鎖,它會調用 AQS 的 tryRelease 方法(取決于具體實作類),抛 IllegalMonitorStateException 異常。​

    說明三:在 Lock 對象的 lock 方法實作中可能抛出 unchecked 異常, 産生的後果與說明二相同。​

  7. 【強制】在使用嘗試機制來擷取鎖的方式中,進入業務代碼塊之前,必須 先判斷目前線程是否持有鎖。鎖的釋放規則與鎖的阻塞等待方式相同。 說明:Lock 對象的 unlock 方法在執行時,它會調用 AQS 的 tryRelease 方法(取決于具體實作類),如果目前線程不持有鎖,則抛 出 IllegalMonitorStateException 異常。​
  8. 【強制】多線程并行處理定時任務時,Timer 運作多個 TimeTask 時, 隻要其中之一沒有捕獲抛出的異常,其它任務便會自動終止運作,使用 ScheduledExecutorService 則沒有這個問題。

八、控制語句​

1. 【強制】在一個 switch 塊内,每個 case 要麼通過continue/ break/ return 等來終止,要麼注釋說明程式将繼續執行到哪一個 case 為止;在一個 switch 塊内,都必須包含一個 default語句并且放在最後,即使它什麼代碼也沒有。

2. 【強制】當 switch 括号内的變量類型為 String 并且此變量為外部參數時,必須先進行 null判斷。

3. 【強制】在 if/else/for/while/do 語句中必須使用大括号。

說明:即使隻有一行代碼,也禁止不采用大括号的編碼方式:

if (condition)statements;

  1. 【強制】三目運算符 condition? 表達式 1 : 表達式 2 中,高度注意表 達式 1 和 2 在類型對齊時,可能抛出因自動拆箱導緻的 NPE 異常。 說明:以下兩種場景會觸發類型對齊的拆箱操作:

    1) 表達式 1 或表達式 2 的值隻要有一個是原始類型。

    2) 表達式 1 或表達式 2 的值的類型不一緻,會強制拆箱更新成表示範圍更大的那個類型。

    反例:

    Integer a = 1;

    Integer b = 2;

    Integer c = null;

    Boolean flag = false;

    // a*b 的結果是 int類型 ,那麼 c 會強制拆箱成 int 類型,抛出 NPE 異常

    Integer result=(flag? a*b : c);

  2. 【強制】在高并發場景中,避免使用”等于”判斷作為中斷或退出的條件。 說明:如果并發控制沒有處理好,容易産生等值判斷被“擊穿”的情況,使用大于或小于的區間判斷條件來代替。
  3. 【推薦】表達異常的分支時,少用 if-else 方式,這種方式可以改寫成: if (condition) {

    ...

    return obj;

    }

    // 接着寫 else 的業務邏輯代碼;

    說明:如果非使用 if()...else if()...else...方式表達邏輯,避免後續代碼維護困難,請勿超過 3 層。

  4. 【推薦】循環體中的語句要考量性能,以下操作盡量移至循環體外處理, 如定義對象、變量、擷取資料庫連接配接,進行不必要的 try-catch 操作(這 個 try-catch 是否可以移至循環體外)。

九、注釋規約

1. 【強制】類、類屬性、類方法的注釋必須使用 Javadoc 規範,使用/**内容*/格式,不得使用// xxx 方式。

說明:在 IDE 編輯視窗中,Javadoc 方式會提示相關注釋,生成 Javadoc 可以正确輸出相應注釋;在 IDE 中,工程調用方法時,不進入方法即可懸浮提示方法、參數、傳回值的意義,提高閱讀效率。

  1. 【強制】所有的抽象方法(包括接口中的方法)必須要用 Javadoc 注釋、除了傳回值、參數、異常說明外,還必須指出該方法做什麼事情,實作什麼功能。 說明:對子類的實作要求,或者調用注意事項,請一并說明。
  2. 【強制】所有的類都必須添加建立者和建立日期。 說明:在設定模闆時,注意 IDEA 的@author 為`${USER}`,而 eclipse 的@author 為`${user}`,大小寫有差別,而日期的設定統一為 yyyy/MM/dd 的格式。
  3. 【強制】方法内部單行注釋,在被注釋語句上方另起一行,使用//注釋。方法内部多行注釋使用/* */注釋,注意與代碼對齊。
  4. 【強制】所有的枚舉類型字段必須要有注釋,說明每個資料項的用途。
  5. 【推薦】代碼修改的同時,注釋也要進行相應的修改,尤其是參數、傳回值、異常、核心邏輯等的修改。
  6. 【參考】謹慎注釋掉代碼。在上方詳細說明,而不是簡單地注釋掉。如果無用,則删除。 說明:代碼被注釋掉有兩種可能性:1)後續會恢複此段代碼邏輯。2)永久不用。前者如果沒有備注資訊,難以知曉注釋動機。後者建議直接删掉即可,假如需要查閱曆史代碼,登入代碼倉庫即可。
  7. 【參考】對于注釋的要求:第一、能夠準确反映設計思想和代碼邏輯;第二、能夠描述業務含義,使别的程式員能夠迅速了解到代碼背後的資訊。完全沒有注釋的大段代碼對于閱讀者形同天書,注釋是給自己看的,即使隔很長時間,也能清晰了解當時的思路;注釋也是給繼任者看的,使其能夠快速接替自己的工作。
  8. 【參考】特殊注釋标記,請注明标記人與标記時間。注意及時處理這些标記,通過标記掃描,經常清理此類标記。線上故障有時候就是來源于這些标記處的代碼。

1) 待辦事宜(TODO)(标記人,标記時間,[預計處理時間])

表示需要實作,但目前還未實作的功能。這實際上是一個 Javadoc 的标簽,目前的 Javadoc 還沒有實作,但已經被廣泛使用。隻能應用于類,接口和方法(因為它是一個 Javadoc 标簽)。

2) 錯誤,不能工作(FIXME):(标記人,标記時間,[預計處理時間])

在注釋中用 FIXME 标記某代碼是錯誤的,而且不能工作,需要及時糾正的情況。

其他

  1. 【強制】在使用正規表達式時,利用好其預編譯功能,可以有效加快正則比對速度。 說明:不要在方法體内定義:Pattern pattern = Pattern.compile(“規則”);
  2. 【強制】避免用 Apache Beanutils 進行屬性的 copy。 說明:Apache BeanUtils 性能較差,可以使用其他方案比如 Spring BeanUtils, Cglib BeanCopier,注意均是淺拷貝。
  3. 【強制】velocity 調用 POJO 類的屬性時,直接使用屬性名取值即可,模闆引擎會自動按規範調用 POJO 的 getXxx(),如果是 boolean 基本資料類型變量(boolean 命名不需要加 is 字首),會自動調用 isXxx()方法。 說明:注意如果是 Boolean 包裝類對象,優先調用 getXxx()的方法。
  4. 【強制】注意 Math.random() 這個方法傳回是 double 類型,注意取值的範圍 0≤x<1(能夠取到零值,注意除零異常),如果想擷取整數類型的随機數,不要将 x 放大 10 的若幹倍然後取整,直接使用 Random 對象的 nextInt 或者 nextLong 方法。
  5. 【推薦】不要在視圖模闆中加入任何複雜的邏輯。 說明:根據 MVC 理論,視圖的職責是展示,不要搶模型和控制器的活。
  6. 【推薦】及時清理不再使用的代碼段或配置資訊。

說明:對于垃圾代碼或過時配置,堅決清理幹淨,避免程式過度臃腫, 代碼備援。

正例:對于暫時被注釋掉,後續可能恢複使用的代碼片斷,在注釋代碼 上方,統一規定使用三個斜杠(///)來說明注釋掉代碼的理由。

繼續閱讀