下載原版阿里JAVA開發手冊 【阿里巴巴Java開發手冊v1.2.0】html
本文主要是對照阿里開發手冊,註釋本身在工做中運用狀況。程序員
本文內容:命名風格、常量定義、代碼風格、控制語句、註釋規約
spring
本文難度係數爲一星(★)數據庫
第一篇 點評阿里JAVA手冊之編程規約(命名風格、常量定義、代碼風格、控制語句、註釋規約)編程
第二篇 點評阿里JAVA手冊之編程規約(OOP 規約 、集合處理 、併發處理 、其餘)json
第三篇 點評阿里JAVA手冊之異常日誌(異常處理 日誌規約 )windows
第四篇 點評阿里JAVA手冊之MySQL數據庫 (建表規約、索引規約、SQL語句、ORM映射)設計模式
代碼的字裏行間流淌的是軟件生命中的血液,質量的提高是儘量少踩坑,杜絕踩重複的坑,切實提高質量意識。另外,現代軟件架構都須要協同開發完成,高效協做即下降協同成本,提高溝通效率,所謂無規矩不成方圓,無規範不能協做。衆所周知,制訂交通法規表面上是要限制行車權,其實是保障公衆的人身安全。試想若是沒有限速,沒有紅綠燈,誰還敢上路行駛。對軟件來講,適當的規範和標準毫不是消滅代碼內容的創造性、優雅性,而是限制過分個性化,以一種廣泛承認的統一方式一塊兒作事,提高協做效率。api
(一) 命名風格數組
1. 【強制】 代碼中的命名均不能如下劃線或美圓符號開始,也不能如下劃線或美圓符號結束。
反例: _name / __name / $Object / name_ / name$ / Object$
【點評】規則好,嚴格遵循。
2.【強制】 代碼中的命名嚴禁使用拼音與英文混合的方式,更不容許直接使用中文的方式。
說明:正確的英文拼寫和語法可讓閱讀者易於理解,避免歧義。注意,即便純拼音命名方式,也要避免採用。
正例: alibaba / taobao / youku / hangzhou 等國際通用的名稱,可視同英文。
反例: DaZhePromotion [打折] / getPingfenByName() [評分] / int 某變量 = 3
【點評】 規則好,嚴格遵循。
3.【強制】類名使用 UpperCamelCase 風格,必須聽從駝峯形式,但如下情形例外:DO / BO / DTO / VO / AO
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
【點評】 規則好,嚴格遵循。
4.【強制】方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須聽從 駝峯形式。 正例: localValue / getHttpMessage() / inputUserId
【點評】 規則好,嚴格遵循。
5. 【強制】常量命名所有大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。
正例: MAX_STOCK_COUNT 反例: MAX_COUNT
【點評】 規則好,在項目中嚴格遵循。
6.【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類 命名以它要測試的類的名稱開始,以 Test 結尾。
【點評】 規則好,嚴格遵循。
7. 【強制】中括號是數組類型的一部分,數組定義以下:String[] args; 反例:使用 String args[]的方式來定義。
【點評】 規則好,嚴格遵循。
8. 【強制】POJO 類中布爾類型的變量,都不要加 is,不然部分框架解析會引發序列化錯誤。 反例:定義爲基本數據類型 Boolean isDeleted;的屬性,它的方法也是 isDeleted(),RPC
框架在反向解析的時候,「覺得」對應的屬性名稱是 deleted,致使屬性獲取不到,進而拋出異 常。
【點評】 存疑,若是數據庫設計表字段,用is開頭的數據庫字段。 進入orm時通常自動生成實體類代碼,極可能存在。本身在設計數據庫時,多用flag結尾做爲tinyint去表示布爾型,不存在此狀況。
9.【強制】包名統一使用小寫,點分隔符之間有且僅有一個天然語義的英語單詞。包名統一使用 單數形式,可是類名若是有複數含義,類名可使用複數形式。 正例: 應用工具類包名爲 com.alibaba.open.util、類名爲 MessageUtils(此規則參考 spring 的框架結構)
【點評】規則好,之後在項目中遵循。
目前代碼中有com.wxhealth.util.wechat。
10.【強制】杜絕徹底不規範的縮寫,避免望文不知義。 反例: AbstractClass「縮寫」命名成 AbsClass;condition「縮寫」命名成 condi,此類 隨意縮寫嚴重下降了代碼的可閱讀性。
【點評】規則好,嚴格遵循。
11.【推薦】若是使用到了設計模式,建議在類名中體現出具體模式。 說明:將設計模式體如今名字中,有利於閱讀者快速理解架構設計思想。
正例:public class OrderFactory; public class LoginProxy; public class ResourceObserver;
【點評】規則好,嚴格遵循。
12.【推薦】接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔性,並加上有效的 Javadoc 註釋。儘可能不要在接口裏定義變量,若是必定要定義變量,確定是與接口方法相關,而且是整個應用的基礎常量。
正例:接口方法簽名:void f();
接口基礎常量表示:String COMPANY = "alibaba";
反例:接口方法定義:public abstract void f();
說明:JDK8 中接口容許有默認實現,那麼這個 default 方法,是對全部實現類都有價值的默認實現。
【點評】規則好,不多注意到這樣使用。
在interface裏面的變量都是public static final 的。因此你能夠這樣寫:
public static final int i=10;
或則
int i=10;(能夠省略掉一部分) 注意在聲明的時候要給變量賦予初值。
首先你要弄清接口的含義.接口就是提供一種統一的’協議’,而接口中的屬性也屬於’協議’中的成員.它們是公共的,靜態的,最終的常量.至關於全局常量.
抽象類是不’徹底’的類,至關因而接口和具體類的一箇中間層.即知足接口的抽象,也知足具體的實現.若是接口能夠定義變量,可是接口中的方法又都是抽象的,在接口中沒法經過行爲來修改屬性。有的人會說了,沒有關係,能夠經過實現接口的對象的行爲來修改接口中的屬性。這固然沒有問題,可是考慮這樣的狀況。若是接口A中有一個public訪問權限的靜態變量a。按照Java的語義,咱們能夠不經過實現接口的對象來訪問變量a,經過A.a = xxx;就能夠改變接口中的變量a的值了。正如抽象類中是能夠這樣作的,那麼實現接口A的全部對象也都會自動擁有這一改變後的a的值了,也就是說一個地方改變了a,全部這些對象中a的值也都跟着變了。這和抽象類有什麼區別呢,怎麼體現接口更高的抽象級別呢,怎麼體現接口提供的統一的協議呢,那還要接口這種抽象來作什麼呢?因此接口中不能出現變量,若是有變量,就和接口提供的統一的抽象這種思想是抵觸的。因此接口中的屬性必然是常量,只能讀不能改,這樣才能爲實現接口的對象提供一個統一的屬性。通俗的講,你認爲是要變化的東西,就放在你本身的實現中,不能放在接口中去,接口只是對一類事物的屬性和行爲更高層次的抽象。對修改關閉,對擴展(不一樣的實現implements)開放,接口是對開閉原則的一種體現。轉自:http://blog.csdn.net/ameyume/article/details/6189749
13. 接口和實現類的命名有兩套規則:
1)【強制】對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務必定是接口,內部的實現類用 Impl 的後綴與接口區別。
正例:CacheServiceImpl 實現 CacheService 接口。
2)【推薦】 若是是形容能力的接口名稱,取對應的形容詞作接口名(一般是–able 的形式)。
正例:AbstractTranslator 實現 Translatable。
【點評】規則好,使用中本身多這樣使用:IApiProcessor
14.【參考】枚舉類名建議帶上 Enum 後綴,枚舉成員名稱須要全大寫,單詞間用下劃線隔開。 說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。
正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS / UNKOWN_REASON。
【點評】規則好,嚴格遵循。
15.【參考】各層命名規約:
A) Service/DAO 層方法命名規約
1) 獲取單個對象的方法用 get 作前綴。
【點評】規則好,嚴格遵循。
2) 獲取多個對象的方法用 list 作前綴。
【點評】規則存疑 ,本身用get開頭,實體類名加List 。getOrderListByName()
3) 獲取統計值的方法用 count 作前綴。
【點評】規則存疑 ,本身用get開頭,實體類名加Count 。getOrderCountByName()
4) 插入的方法用 save(推薦)或 insert 作前綴。
【點評】規則好,嚴格遵循。
5) 刪除的方法用 remove(推薦)或 delete 作前綴。
【點評】規則好,嚴格遵循。
6) 修改的方法用 update 作前綴。
【點評】規則好,嚴格遵循。
B) 領域模型命名規約
1) 數據對象:xxxDO,xxx 即爲數據表名。
2) 數據傳輸對象:xxxDTO,xxx 爲業務領域相關的名稱。
3) 展現對象:xxxVO,xxx 通常爲網頁名稱。
【點評】規則存疑,數據對象,通常與表名相同,可能命名不一樣。數據對象也同時用於數據傳輸對象和展現對象。
4) POJO 是 DO/DTO/BO/VO 的統稱,禁止命名成 xxxPOJO。
【點評】規則好,嚴格遵循。
(二) 常量定義
1. 【強制】不容許任何魔法值(即未經定義的常量)直接出如今代碼中。
反例: String key = "Id#taobao_" + tradeId;
cache.put(key, value);
【點評】規則好,在代碼中儘可能遵循。可是,咱們在api接口中有:
Map<String, Object> response = new HashMap<String, Object>();
response.put("code", 0);
response.put("orderflag", orderflag);
將response轉化爲json格式,經過rest api發佈。
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 定義。
【點評】規則存疑,直接在類中定義跨應用共享常量。如Integer.MAX_VALUE 和Integer.MIN_VALUE。
public final class Integer extends Number implements Comparable<Integer> {
/**
* A constant holding the minimum value an {@code int} can
* have, -2<sup>31</sup>.
*/
public static final int MIN_VALUE = 0x80000000;
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
*/
public static final int MAX_VALUE = 0x7fffffff;
。。。。。。
5. 【推薦】若是變量值僅在一個範圍內變化,且帶有名稱以外的延伸屬性,定義爲枚舉類。下面 正例中的數字就是延伸信息,表示星期幾。
正例:public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);}
【點評】規則好,已經遵循。
(三) 代碼風格
1. 【強制】大括號的使用約定。若是是大括號內爲空,則簡潔地寫成{}便可,不須要換行;
若是是非空代碼塊則:
1) 左大括號前不換行。
2) 左大括號後換行。
3) 右大括號前換行。
4) 右大括號後還有 else 等代碼則不換行;表示終止的右大括號後必須換行。
【點評】規則好,已經遵循。
2. 【強制】左小括號和字符之間不出現空格;一樣,右小括號和字符之間也不出現空格。
詳見第 5 條下方正例提示。
反例:if (空格 a == b 空格)
【點評】規則好,已經遵循。
3. 【強制】if/for/while/switch/do 等保留字與括號之間都必須加空格。
【點評】規則好,未遵循。 在Eclipse下面,用格式化代碼ctrl+shift+f 是這樣的。
4. 【強制】任何二目、三目運算符的左右兩邊都須要加一個空格。
說明:運算符包括賦值運算符=、邏輯運算符&&、加減乘除符號等。
【點評】規則好,未遵循。 在Eclipse下面,用格式化代碼ctrl+shift+f 是這樣的。
5. 【強制】縮進採用 4 個空格,禁止使用 tab 字符。
說明:若是使用 tab 縮進,必須設置 1 個 tab 爲 4 個空格。
IDEA 設置 tab 爲 4 個空格時, 請勿勾選 Use tab character;
而在 eclipse 中,必須勾選insert spaces for tabs。
正例: (涉及 1-5 點)
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. 【強制】單行字符數限制不超過 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);
【點評】規則好,已經遵循。
7. 【強制】方法參數在定義和傳入時,多個參數逗號後邊必須加空格。 正例:下例中實參的"a",後邊必需要有一個空格。 method("a", "b", "c");
【點評】規則好,已經遵循。
8. 【強制】IDE 的 text file encoding 設置爲 UTF-8; IDE 中文件的換行符使用 Unix 格式, 不要使用 windows 格式。
【點評】規則好,已經遵循。
9. 【推薦】沒有必要增長若干空格來使某一行的字符與上一行對應位置的字符對齊。
正例: int a = 3;
long b = 4L;
float c = 5F;
StringBuffer sb = new StringBuffer();
說明:增長 sb 這個變量,若是須要對齊,則給 a、b、c 都要增長几個空格,在變量比較多的狀況下,是一種累贅的事情。
【點評】規則好,已經遵循。
10. 【推薦】方法體內的執行語句組、變量的定義語句組、不一樣的業務邏輯之間或者不一樣的語義之間插入一個空行。相同業務邏輯和語義之間不須要插入空行。
說明:沒有必要插入多個空行進行隔開
【點評】規則好,已經遵循。
(四) 控制語句
1. 【強制】在一個 switch 塊內,每一個 case 要麼經過 break/return 等來終止,要麼註釋說明程 序將繼續執行到哪個 case 爲止;在一個 switch 塊內,都必須包含一個 default 語句而且 放在最後,即便它什麼代碼也沒有。
【點評】規則好,嚴格遵循。
2. 【強制】在 if/else/for/while/do 語句中必須使用大括號。即便只有一行代碼,避免使用 單行的形式:if (condition) statements;
【點評】規則好,嚴格遵循。
3. 【推薦】表達異常的分支時,少用 if-else 方式,這種方式能夠改寫成:
if (condition) { ... return obj; }
// 接着寫 else 的業務邏輯代碼; 說明:若是非得使用 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 Guideline.」); return; }
【點評】規則好,嚴格遵循。
4. 【推薦】除經常使用方法(如 getXxx/isXxx)等外,不要在條件判斷中執行其它複雜的語句,將複雜邏輯判斷的結果賦值給一個有意義的布爾變量名,以提升可讀性。
說明:不少 if 語句內的邏輯至關複雜,閱讀者須要分析條件表達式的最終結果,才能明確什麼樣的條件執行什麼樣的語句,那麼,若是閱讀者分析邏輯表達式錯誤呢? 正例: //僞代碼以下 final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) { ... }
反例: if ((file.open(fileName, "w") != null) && (...) || (...)) { ... }
【點評】規則好,嚴格遵循。
5. 【推薦】循環體中的語句要考量性能,如下操做盡可能移至循環體外處理,如定義對象、變量、 獲取數據庫鏈接,進行沒必要要的 try-catch 操做(這個 try-catch 是否能夠移至循環體外)。
【點評】規則好,嚴格遵循。
6. 【推薦】接口入參保護,這種場景常見的是用於作批量操做的接口。
7. 【參考】下列情形,須要進行參數校驗:
1) 調用頻次低的方法。
2) 執行時間開銷很大的方法。此情形中,參數校驗時間幾乎能夠忽略不計,但若是由於參數錯誤致使中間執行回退,或者錯誤,那得不償失。
3) 須要極高穩定性和可用性的方法。
4) 對外提供的開放接口,無論是 RPC/API/HTTP 接口。
5) 敏感權限入口。
【點評】規則好,嚴格遵循。
8. 【參考】下列情形,不須要進行參數校驗:
1) 極有可能被循環調用的方法。但在方法說明裏必須註明外部參數檢查要求。
2) 底層調用頻度比較高的方法。畢竟是像純淨水過濾的最後一道,參數錯誤不太可能到底 層纔會暴露問題。通常 DAO 層與 Service 層都在同一個應用中,部署在同一臺服務器中,所 以 DAO 的參數校驗,能夠省略。
3) 被聲明成 private 只會被本身代碼所調用的方法,若是可以肯定調用方法的代碼傳入參 數已經作過檢查或者確定不會有問題,此時能夠不校驗參數
【點評】規則好,嚴格遵循。
(五) 註釋規約
1. 【強制】類、類屬性、類方法的註釋必須使用 Javadoc 規範,使用/**內容*/格式,不得使用 //xxx 方式。 說明:在 IDE 編輯窗口中,Javadoc 方式會提示相關注釋,生成 Javadoc 能夠正確輸出相應注 釋;在 IDE 中,工程調用方法時,不進入方法便可懸浮提示方法、參數、返回值的意義,提升 閱讀效率。
【點評】規則好,嚴格遵循。本身目前未嚴格遵照。
Javadoc 規範參考:http://www.2cto.com/kf/201607/521803.html
http://www.cnblogs.com/bluestorm/archive/2012/10/04/2711329.html
2. 【強制】全部的抽象方法(包括接口中的方法)必需要用 Javadoc 註釋、除了返回值、參數、 異常說明外,還必須指出該方法作什麼事情,實現什麼功能。 說明:對子類的實現要求,或者調用注意事項,請一併說明。
【點評】規則好,嚴格遵循。
3. 【強制】全部的類都必須添加建立者和建立日期。
【點評】規則好,嚴格遵循。本身目前未嚴格遵照。
4. 【強制】方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋。方法內部多行註釋 使用/* */註釋,注意與代碼對齊。
【點評】規則好,嚴格遵循。本身目前未嚴格遵照。
5. 【強制】全部的枚舉類型字段必需要有註釋,說明每一個數據項的用途。
【點評】規則好,嚴格遵循。本身目前未嚴格遵照。
6. 【推薦】與其「半吊子」英文來註釋,不如用中文註釋把問題說清楚。專有名詞與關鍵字保持 英文原文便可。 反例:「TCP 鏈接超時」解釋成「傳輸控制協議鏈接超時」,理解反而費腦筋。
【點評】規則好,嚴格遵循。
7. 【推薦】代碼修改的同時,註釋也要進行相應的修改,尤爲是參數、返回值、異常、核心邏輯 等的修改。 說明:代碼與註釋更新不一樣步,就像路網與導航軟件更新不一樣步同樣,若是導航軟件嚴重滯後, 就失去了導航的意義。
【點評】規則好,嚴格遵循。
8. 【參考】合理處理註釋掉的代碼。在上方詳細說明,而不是簡單的註釋掉。若是無用,則刪除。 說明:代碼被註釋掉有兩種可能性:1)後續會恢復此段代碼邏輯。2)永久不用。前者若是沒有備註信息,難以知曉註釋動機。後者建議直接刪掉(代碼倉庫保存了歷史代碼)。
【點評】規則好,嚴格遵循。
9. 【參考】對於註釋的要求:第1、可以準確反應設計思想和代碼邏輯;第2、可以描述業務含 義,使別的程序員可以迅速瞭解到代碼背後的信息。徹底沒有註釋的大段代碼對於閱讀者形同
天書,註釋是給本身看的,即便隔很長時間,也能清晰理解當時的思路;註釋也是給繼任者看的,使其可以快速接替本身的工做。
【點評】規則好,嚴格遵循。
10. 【參考】好的命名、代碼結構是自解釋的,註釋力求精簡準確、表達到位。避免出現註釋的 一個極端:過多過濫的註釋,代碼的邏輯一旦修改,修改註釋是至關大的負擔。 反例: // put elephant into fridge put(elephant, fridge); 方法名 put,加上兩個有意義的變量名 elephant 和 fridge,已經說明了這是在幹什麼,語 義清晰的代碼不須要額外的註釋。
【點評】規則好,嚴格遵循。
11. 【參考】特殊註釋標記,請註明標記人與標記時間。注意及時處理這些標記,經過標記掃描, 常常清理此類標記。線上故障有時候就是來源於這些標記處的代碼。
1) 待辦事宜(TODO):( 標記人,標記時間,[預計處理時間]) 表示須要實現,但目前還未實現的功能。這其實是一個 Javadoc 的標籤,目前的 Javadoc 尚未實現,但已經被普遍使用。只能應用於類,接口和方法(由於它是一個 Javadoc 標籤)。
2) 錯誤,不能工做(FIXME):(標記人,標記時間,[預計處理時間]) 在註釋中用 FIXME 標記某代碼是錯誤的,並且不能工做,須要及時糾正的狀況
【點評】規則好,嚴格遵循。