代碼不規範,這些問題你必定遇到過

統計了內部一個準備開源的Java項目不規範的代碼數量及種類,數據比較敏感,不便公開。可是最常常出現的不規範類型能夠說一下。java

早先本身也去分享過代碼規範,試着猜過哪些代碼規範問題可能會犯,但靠猜不能解決問題,用內部的項目插件掃了一下,統計全部出現代碼問題以下。spring

代碼規範問題

命名

最多見的問題,代碼規範中接近大半的命名問題都有犯。編程

1 包名應該所有小寫緩存

【強制】包名統一使用小寫,點分隔符之間有且僅有一個天然語義的英語單詞。包名統一使用 單數形式,可是類名若是有複數含義,類名可使用複數形式。 正例:應用工具類包名爲 com.alibaba.ai.util、類名爲 MessageUtils(此規則參考 spring 的框架結構)安全

2 命名不能以_或者$開頭服務器

代碼中的命名均不能如下劃線或美圓符號開始,也不能如下劃線或美圓符號結束。app

反例:__name / $name框架

3 類名使用UpperCamelCase風格ide

【強制】類名使用 UpperCamelCase 風格,但如下情形例外:DO / BO / DTO / VO / AO /工具

PO / UID 等。

正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion

反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

4 方法名沒有使用lowerCamelCase風格

【強制】方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須聽從 駝峯形式。 正例: localValue / getHttpMessage() / inputUserId

5 常量命名應該所有大寫而且如下劃線分隔

【強制】常量命名所有大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。

正例:MAX_STOCK_COUNT 反例:MAX_COUNT

6 抽象類名應該以Abstract或者Base開頭

【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類

命名以它要測試的類的名稱開始,以 Test 結尾。

7 POJO布爾類型變量,不要加is前綴

【強制】POJO 類中布爾類型的變量,都不要加 is 前綴,不然部分框架解析會引發序列化錯誤。 反例:定義爲基本數據類型 Boolean isDeleted 的屬性,它的方法也是 isDeleted(),RPC框架在反向解析的時候,「誤覺得」對應的屬性名稱是 deleted,致使屬性獲取不到,進而拋 出異常。

常量定義

1 魔法值

【強制】不容許任何魔法值(即未經預先定義的常量)直接出如今代碼中。

反例:

String key = "Id#taobao_" + tradeId;

cache.put(key, value);

2 Long類型的值,要以大寫的L結尾

【強制】在 long 或者 Long 賦值時,數值後使用大寫的 L,不能是小寫的 l,小寫容易跟數字 1 混淆,形成誤解。 說明:Long a = 2l; 寫的是數字的 21,仍是 Long 型的 2?

3 不要一個類維護全部的常量

【推薦】不要使用一個常量類維護全部常量,要按常量功能進行歸類,分開維護。 說明:大而全的常量類,雜亂無章,使用查找功能才能定位到修改的常量,不利於理解和維護。

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

4 應該使用常量或者確認值的內容來調用equals

【強制】Object 的 equals 方法容易拋空指針異常,應使用常量或肯定有值的對象來調用 equals。

正例:"test".equals(object);

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

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

代碼格式

1 代碼行數太長

【推薦】單個方法的總行數不超過80行。有效代碼行數40行左右

說明:包括方法簽名、結束右大括號、方法內代碼、註釋、空行、回車及任何不可見字符的總行數不超過80

行。

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

2 文件編碼不統一

【強制】IDE 的 text file encoding 設置爲 UTF-8; IDE 中文件的換行符使用 Unix 格式,不要使用 Windows 格式。

集合處理

1 初始化HashMap等集合時,儘可能指定初始值大小

【推薦】集合初始化時,指定集合初始值大小。 說明:HashMap 使用 HashMap(int initialCapacity) 初始化。

正例:initialCapacity=(須要存儲的元素個數 / 負載因子) + 1。注意負載因子(即 loaderfactor)默認爲0.75,若是暫時沒法肯定初始值大小,請設置爲16(即默認值)。

反例:HashMap須要放置1024個元素,因爲沒有設置容量初始大小,隨着元素不斷增長,容量 7 次被迫擴大,resize須要重建hash表,嚴重影響性能。

2 遍歷Map的方式

【推薦】使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷。

說明:keySet 實際上是遍歷了 2 次,一次是轉爲 Iterator 對象,另外一次是從 hashMap 中取出 key 所對應的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中,效率更高。若是是 JDK8,使用 Map.foreach 方法。 正例:values()返回的是 V 值集合,是一個 list 集合對象;keySet()返回的是 K 值集合,是

一個 Set 集合對象;entrySet()返回的是 K-V 值組合集合。

控制語句

1 控制層數不要過高

表達異常的分支時,少用 if-else 方式,這種方式能夠改寫

if (condition) {

​ ...

​ return obj;

}

若是非得使用 if()...else if()...else...方式表達邏輯,避免後續維護護困難,請勿超過 3 層。

超過 3 層的 if-else 的邏輯判斷代碼能夠 其中衛語句示例以下:

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;

}

2 不要在條件中使用複雜的表達式

【推薦】除經常使用方法(如 getXxx/isXxx)等外,不要在條件判斷中執行其它複雜的語句,將 複雜邏輯判斷的結果賦值給一個有意義的布爾變量名,以提升可讀性。 說明:不少 if 語句內的邏輯至關複雜,閱讀者須要分析條件表達式的最終結果,才能明確什麼 樣的條件執行什麼樣的語句,那麼,若是閱讀者分析邏輯表達式錯誤呢? 正例:

// 僞代碼以下

final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);

if (existed) {

...

}

反例:

if ((file.open(fileName, "w") != null) && (...) || (...)) {

...

}

3 if語句缺乏大括號

【強制】在 if/else/for/while/do 語句中必須使用大括號。即便只有一行代碼,避 單行的編碼方式:if (condition) statements;

註釋規約

1 使用行尾註釋

【強制】方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋。方法內部多行註釋 使用/* */註釋,注意與代碼對齊。

2 缺乏@author信息

【強制】全部的類都必須添加建立者和建立日期。

@author

@date

3 使用Javadoc註釋

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

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

8 及時清理再也不使用的代碼段或配置信息

【推薦】及時清理再也不使用的代碼段或配

說明:對於垃圾代碼或過期配置,堅定清理乾淨,避免程序過分臃腫,代碼冗餘。

正例:對於暫時被註釋掉,後續可能恢復使用的代碼片段,在註釋代碼上方,統一規定使用三 個斜槓(///)來講明註釋掉代碼的理由。

4 方法的參數缺乏javadoc註釋

【強制】全部的抽象方法(包括接口中的方法)必需要用 Javadoc 註釋、除了返回值、參數、 異常說明外,還必須指出該方法作什麼事情,實現什麼功能。

說明:對子類的實現要求,或者調用注意事項,請一併說明。

5 枚舉字段缺乏註釋

【強制】全部的枚舉類型字段必需要有註釋,說明每一個數據項的用途。

其它

1 循環體內字符串的拼接採用StringBuilder的方式

【推薦】循環體內,字符串的鏈接方式,使用 StringBuilder 的 append 方法進行擴展。 說明:下例中,反編譯出的字節碼文件顯示每次循環都會 new 出一個 StringBuilder 對象, 而後進行 append 操做,最後經過 toString 方法返回 String 對象,形成內存資源浪費。

反例:

String str = "start";

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

str = str + "hello";

}

2 顯示建立線程池

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

說明:使用線程池的好處是減小在建立和銷燬線程上所消耗的時間以及系統資源的開銷,解決 資源不足的問題。若是不使用線程池,有可能形成系統建立大量同類線程而致使消耗完內存或 者「過分切換」的問題。

3 參數列表長度過長

【強制】相同參數類型,相同業務含義,纔可使用 Java 的可變參數,避免使用 Object。 說明:可變參數必須放置在參數列表的最後。(提倡同窗們儘可能不用可變參數編程) 正例:public List listUsers(String type, Long... ids) {...}

4 多個參數進行換行

方法調用中的多個參數須要換行時,在逗號後進行。

5 重定向問題

【參考】服務器內部重定向使用 forward;外部重定向地址使用 URL 拼裝工具類來生成,不然 會帶來 URL 維護不一致的問題和潛在的安全風險。

最後

以上爲寫代碼時最常犯的問題,以及在代碼規範上提出的處理措施。

相關文章
相關標籤/搜索