Java編碼規範

java編碼規範(日常編碼總結,規範專案組員有統一的規範,方便合作,查錯,重構等)當你拋棄規範隨心所意的寫程式碼時,等你之後再回來閱讀時真有的一種全部刪掉重寫的衝動。

前言

如果這份規範中有不合理的地方,歡迎提issue/提PR等各種形式進行完善。

如果您有更好的程式碼風格未在本規範中列出,歡迎提issue/提PR等各種形式進行完善。

本規範最後一部分

業務規範

僅根據本人所在公司情況制定(遊戲開發),請酌情考慮使用。

本project還在完善和驗證中,希望和大家一起寫出優雅而實用的程式碼。

常用開發工具下載

IDE(IDEA/eclipse or other)

mysql (5。6+)

mysql client(navicat/mysql workbeach)

xshell and xftp

jdk1。7

emeditor

apache ant

apache maven

tortoise svn 64位

一。命名規範

1。【強制】 程式碼中的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。

說明:正確的英文拼寫和語法可以讓閱讀者易於理解,避免歧義。注意,即使純拼音命名方式也要避免採用。不會的單詞請谷歌翻譯。 反例:

DaZhePromotion [打折] / getPingfenByName() [評分] / int 某變數 = 3

正例:

alibaba / taobao / youku / hangzhou

等國際通用的名稱,可視同英文。

2。 類名使用 UpperCamelCase 風格(首字母大寫),必須遵從駝峰形式。

正例:

MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion

反例:

macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

3。 方法名、引數名、成員變數、區域性變數都統一使用 lowerCamelCase 風格(首字母小寫),必須遵從駝峰形式。

正例:

localValue / getHttpMessage() / inputUserId

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

正例:

MAX_STOCK_COUNT

反例:

MAX_COUNT

5。 【強制】包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用單數形式,但是類名如果有複數含義,類名可以使用複數形式。

正例: 應用工具類包名為 com。java。open。util、類名為 MessageUtils(此規則參考spring 的框架結構)

6。 杜絕完全不規範的縮寫,避免望文不知義。

反例:

AbstractClass

“縮寫”命名成

AbsClass

condition

“縮寫”命名成

condi

,此類隨意縮寫嚴重降低了程式碼的可閱讀性。

7。 【推薦】如果使用到了設計模式,建議在類名中體現出具體模式。

說明:將設計模式體現在名字中,有利於閱讀者快速理解架構設計思想。 正例:

public class OrderFactory; public class LoginProxy; public class ResourceObserver;

8。 列舉類名建議帶上 Enum 字尾,列舉成員名稱需要全大寫,單詞間用下劃線隔開。

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

DealStatusEnum

,成員名稱:

SUCCESS / UNKOWN_REASON

9。 【強制】 程式碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束。

反例:

_name / __name / $Object / name_ / name$ / Object$

10。 【推薦】介面類中的方法和屬性不要加任何修飾符號(public 也不要加),保持程式碼的簡潔性,並加上有效的 Javadoc 註釋

11。 原始碼檔案以檔案內容中的最頂層的Java類命名,而且大小寫敏感,副檔名為 。java,同時,檔案的編碼格式統一為UTF-8。

12。 類的命名遵循大駝峰命名法UpperCamelCase,而方法名和變數名的命名遵循小駝峰命名法lowerCamelCase

常量名使用大寫字母表示,單詞之間以下劃線分隔,例如static final int CONNECTION_TIMEOUT = 10000

二。常量定義

1。 【強制】不允許出現任何魔法值(即未經定義的常量)直接出現在程式碼中。

反例:

String key = “Id#taobao_”+tradeId;cache。put(key, value);

2。 【強制】long 或者 Long 初始賦值時,必須使用大寫的 L,不能是小寫的 l,小寫容易跟數字1 混淆,造成誤解。

說明:Long a = 2l; 寫的是數字的 21,還是 Long 型的 2?

3。 【強制】不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護。

如:快取相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。 說明:大而全的常量類,非得使用查詢功能才能定位到修改的常量,不利於理解和維護。

4。 【推薦】常量的複用層次有五層:跨應用共享常量、應用內共享常量、子工程內共享常量、包內共享常量、類內共享常量。

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

5。【推薦】如果變數值僅在一個範圍內變化,且帶有名稱之外的延伸屬性,定義為列舉類。下面

正例中的數字就是延伸資訊,表示星期幾。 正例:

public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7); }

三。 格式規約

1。 【建議】縮排採用 4 個空格,禁止使用 tab 字元。

說明:如果使用 tab 縮排,必須設定 1 個 tab 為 4 個空格。IDEA 設定 tab 為 4 個空格時,請勿勾選

Use tab character

;而在 eclipse 中,必須勾選

insert spaces for tabs

。因為tab很容易造成程式碼對齊方式錯亂,尤其在生成html文件的時候格式會亂掉。

2。 【強制】單行字元數限制不超過 120 個,超出需要換行。

3。 Javadoc

標準的Javadoc常見的標記和含義如下:

/** * Javadoc常見的標記 * * @param 方法引數的說明 * @return 對方法返回值的說明 * @throws 方法丟擲異常的藐視 * @version 模組的版本號 * @author 模組的作者 * @see 參考方向 * @deprecated 標記是否過時 */

四。 OOP規約

1。 【強制】外部正在呼叫或者二方庫依賴的介面,不允許修改方法簽名,避免對介面呼叫方產生影響。介面過時必須加@Deprecated 註解,並清晰地說明採用的新介面或者新服務是什麼。

2。 【強制】定義 DO/DTO/VO 等 POJO 類時,不要設定任何屬性預設值。

反例:POJO 類的 gmtCreate 預設值為 new Date(); , 但是這個屬性在資料提取時並沒有置入具體值,在更新其它欄位時又附帶更新了此欄位,導致建立時間被修改成當前時間。

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

4。 【強制】POJO 類必須寫 toString 方法。使用 IDE 的中工具:source> generate toString時,如果繼承了另一個 POJO 類,注意在前面加一下 super。toString。

說明:在方法執行丟擲異常時,可以直接呼叫 POJO 的 toString()方法列印其屬性值,便於排查問題。

5。 【推薦】當一個類有多個構造方法,或者多個同名方法,這些方法應該按順序放置在一起,便於閱讀。

6。【推薦】 類內方法定義順序依次是:公有方法或保護方法 > 私有方法 > getter/setter方法。

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

7。 【推薦】setter 方法中,引數名稱與類成員變數名稱一致,this。成員名 = 引數名。在getter/setter 方法中,不要增加業務邏輯,增加排查問題的難度。我曾天真的認為這種黑魔法很酷。

反例:

public Integer getData() {if (true) {return data + 100;} else {return data - 100; }}

8。 【推薦】下列情況,宣告成 final 會更有提示性:

1) 不需要重新賦值的變數,包括類屬性、區域性變數。 2) 物件引數前加 final,表示不允許修改引用的指向。 3) 類方法確定不允許被重寫。

9。 【推薦】類成員與方法訪問控制從嚴:

1) 如果不允許外部直接透過 new 來建立物件,那麼構造方法必須是 private。 2) 工具類不允許有 public 或 default 構造方法。 3) 類非 static 成員變數並且與子類共享,必須是 protected。 4) 類非 static 成員變數並且僅在本類使用,必須是 private。 5) 類 static 成員變數如果僅在本類使用,必須是 private。 6) 若是 static 成員變數,必須考慮是否為 final。 7) 類成員方法只供類內部呼叫,必須是 private。 8) 類成員方法只對繼承類公開,那麼限制為 protected。 說明:任何類、方法、引數、變數,嚴控訪問範圍。過於寬泛的訪問範圍,不利於模組解耦。

思考:如果是一個 private 的方法,想刪除就刪除,可是一個 public 的 service 方法,或者一個 public 的成員變數,刪除一下,不得手心冒點汗嗎?變數像自己的小孩,儘量在自己的視線內,變數作用域太大,如果無限制的到處跑,那麼你會擔心的。

四。 集合操作

1。 【強制】不要在 foreach 迴圈裡進行元素的 remove/add 操作。remove 元素請使用 Iterator方式,如果併發操作,需要對 Iterator 物件加鎖。

反例:

List a = new ArrayList();a。add(“1”);a。add(“2”);for (String temp : a) { if (“1”。equals(temp)) { a。remove(temp); } }

正例:

Iterator it = a。iterator();while (it。hasNext()) { String temp = it。next(); if (刪除元素的條件) { it。remove(); } }

五。異常處理

1。【推薦】方法的返回值可以為 null,不強制返回空集合,或者空物件等,必須添加註釋充分說明什麼情況下會返回 null 值。呼叫方需要進行 null 判斷防止 NPE 問題。

2。 【強制】對大段程式碼進行 try-catch,這是不負責任的表現。catch 時請分清穩定程式碼和非穩定程式碼,穩定程式碼指的是無論如何不會出錯的程式碼。對於非穩定程式碼的 catch 儘可能進行區分異常型別,再做對應的異常處理。

3。 【強制】捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它,請將該異常拋給它的呼叫者。最外層的業務使用者,必須處理異常,將其轉化為使用者可以理解的內容。

六。 日誌

1。 【強制】直接return的情況下一定要打日誌,不然根本無法判斷程式碼沒有執行還是在哪個位置被return了。

2。 【強制】異常資訊應該包括兩類資訊:案發現場資訊和異常堆疊資訊。如果不處理,那麼透過關鍵字 throws 往上丟擲。

正例:logger。error(各類引數或者物件 toString + “_” + e。getMessage(), e);

3。 【參考】可以使用 warn 日誌級別來記錄使用者輸入引數錯誤的情況,避免使用者投訴時,無所適從。注意日誌輸出的級別,error 級別只記錄系統邏輯出錯、異常等重要的錯誤資訊。如非必要,請不要在此場景打出 error 級別。

備註: 以上內容摘自<阿里巴巴JAVA程式設計規範>

7。 業務規範

1。 【強制】寫業務邏輯時,一定要把對應的需求連結貼在程式碼註釋裡,方便在和策劃撕逼時方便決定誰該背鍋。

// 月卡增幅 2017/01/04 http://192。168。1。88:8010/index。php?m=story&f=view&storyID=7775 if ((instanceConfig。getInstanceType() & 1) == 1) { // 個人BOSS itemNum += extraAdd; } if (itemConfig。getCarrymax() > 0) { int count = BagApiNew。getItemCount(bag, itemId) + StorageApi。getItemCount(rid, itemId); if (count + itemNum >= itemConfig。getCarrymax()) {// 超出最大囤積上限的時候獲得一部分 LOGGER。error(“{}|{}|玩家領取副本【{}】獎勵【itemId:{},itemNum:{},oldNum:{}】時超出上限【{}】”, rid, role。get(“name”), instanceConfig。getMapid(), itemId, itemNum, count, itemConfig。getCarrymax()); itemNum = itemConfig。getCarrymax() - count; } }

2。 【強制】不要和策劃口頭定需求,有修改或者新增在需求裡體現出來。

3。 【強制】需求做完要自己先測試,未測出bug再打給策劃。然後再和策劃一起做最後bug排查和功能最佳化。嚴禁未經任何自查就扔給策劃,除百你對改動的程式碼100%確認沒有問題。

4。 【強制】方法體一定要有註釋並署名,方便找寫該業務的人做BUG排查。

/** * 請求開啟困惑殿堂面板 * * @param rid rid * author: 小莫 * date: 2017-05-04 10:08 */ public void reqOpenPanel(int rid) { // code }

5。 【強制】方法體中決定不能出現數字(0除外),放在常量類中並加以註釋。如果常量小於3個可以放在本類的頂部(參考常量定義-3)

package rpg。system。task。constant;public interface TaskType { int JIFENGFUMO = 4; int CAIJI = 5; int XIANGYAOFUMO = 8; int BIG_BOSS = 10; //精英任務 int QIYUXUNHUAN = 11; int JINDU = 12; int TIAOZHAN = 13; int TREASURE_BOWL = 14;// 聚寶盆 int QIYUSUIJI = 23; int CANGYUE_ISLAND = 100;}

6。 【強制】型別和Map的key要定義常量類存放於業務模組。

正例:

uparm

模組

constant

包中存放,以

XxxConst

XxxField

命名。

├── uparm│ ├── UparmManager。java│ ├── bean│ │ ├── ComposeBean。java│ │ └── XilianBean。java│ ├── constant│ │ └── ArmFromConst。java│ │ └── ArmField。java│ ├── handler│ │ ├── ReqAddQhFailNumHandler。java│ │ ├── ReqDecomposeHandler。java│ │ └── ReqZyqhHandler。java

Field

內容例如:

public interface LimitTimeTaskField { /** * 任務接受狀態 */ int TASK_ACCEPT_STATE = 1; /** * 任務完成狀態 */ int TASK_COMPLETE_STATE = 2; /** * 限時任務訊息 */ String LIMIT_TIME_TASK_INFO = “LIMIT_TIME_TASK_INFO”; /** * 分組id */ String LIMIT_TIME_TASK_GROUP_ID =“LIMIT_TIME_TASK_GROUP_ID”; }

7。 【強制】在寫業務邏輯的時候儘可能的考慮到發包情況(不要輕信客戶端傳過來的資料),並對發包請求進行攔截,防止非正常玩家透過BUG刷道具。

例:玩家領獎之後要給玩家存一個己領獎的flag,當再次請求的時候就不要重複發獎勵了 。

相關資料

阿里巴巴Java開發手冊v1。2。0-1。pdf

阿里巴巴java程式設計規範2017版。pdf

Android & Java 書寫簡潔規範的程式碼