2017版的阿裏java開發手冊:比較多,只能復制壹部分,妳可以去百度具體的
壹、編程規約?(壹)?命名規約?
1.?強制?代碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束。?
反例:?_name?/?__name?/?$Object?/?name_?/?name$?/?Object$?
2.?強制?代碼中的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。?
說明:正確的英文拼寫和語法可以讓閱讀者易於理解,避免歧義。註意,即使純拼音命名方式
也要避免采用。?
反例:?DaZhePromotion?[打折]?/?getPingfenByName()?[評分]?/?int?某變量?=?3?
正例:?alibaba?/?taobao?/?youku?/?hangzhou?等國際通用的名稱,可視同英文。?
3.?強制類名使用?UpperCamelCase?風格,必須遵從駝峰形式,但以下情形例外:(領域模型
的相關命名)DO?/?BO?/?DTO?/?VO?等。?
正例: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?isSuccess;的屬性,它的方法也是?isSuccess(),RPC
框架在反向解析的時候,“以為”對應的屬性名稱是?success,導致屬性獲取不到,進而拋出異
常。?
9.?強制包名統壹使用小寫,點分隔符之間有且僅有壹個自然語義的英語單詞。包名統壹使用
單數形式,但是類名如果有復數含義,類名可以使用復數形式。?
正例:?應用工具類包名為?com.alibaba.open.util、類名為?MessageUtils(此規則參考
spring?的框架結構)?
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?方法,是對所有實現類都有價值的默
認實現。?
13.?接口和實現類的命名有兩套規則:?
1)強制對於?Service?和?DAO?類,基於?SOA?的理念,暴露出來的服務壹定是接口,內部的實現類用?Impl?的後綴與接口區別。?
正例:CacheServiceImpl?實現?CacheService?接口。?
2)?推薦?如果是形容能力的接口名稱,?取對應的形容詞做接口名?(通常是–able?的形式)?。?正例:AbstractTranslator?實現?Translatable。?
14.?參考枚舉類名建議帶上?Enum?後綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。?
說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。?
正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS?/?UNKOWN_REASON。?
15.?參考各層命名規約:?
A)?Service/DAO?層方法命名規約?
1)?獲取單個對象的方法用?get?做前綴。?
2)?獲取多個對象的方法用?list?做前綴。?
3)?獲取統計值的方法用?count?做前綴。?
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);?
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.?推薦如果變量值僅在壹個範圍內變化用?Enum?類。如果還帶有名稱之外的延伸屬性,必須
使用?Enum?類,下面正例中的數字就是延伸信息,表示星期幾。?
正例:public?Enum?{?MONDAY(1),?TUESDAY(2),?WEDNESDAY(3),?THURSDAY(4),?FRIDAY(5),?SATURDAY(6),?
SUNDAY(7);}?
(三)?格式規約?
1.?強制大括號的使用約定。如果是大括號內為空,則簡潔地寫成{}即可,不需要換行;如果
是非空代碼塊則:?
1)?左大括號前不換行。? 2)?左大括號後換行。? 3)?右大括號前換行。? 4)?右大括號後還有?else?等代碼則不換行;表示終止右大括號後必須換行。?2.?強制?左括號和後壹個字符之間不出現空格;同樣,右括號和前壹個字符之間也不出現空
格。詳見第?5?條下方正例提示。?
3.?強制if/for/while/switch/do?等保留字與左右括號之間都必須加空格。?
4.?強制任何運算符左右必須加壹個空格。?
說明:運算符包括賦值運算符=、邏輯運算符&&、加減乘除符號、三目運算符等。?
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,不用換行?
阿裏巴巴?Java?開發手冊?
——禁止用於商業用途,違者必究——?6?/?37?
}?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?都要增加幾個空格,在變量比較多的
情況下,是壹種累贅的事情。?
阿裏巴巴?Java?開發手冊?
——禁止用於商業用途,違者必究——?7?/?37?
10.?推薦方法體內的執行語句組、變量的定義語句組、不同的業務邏輯之間或者不同的語義
之間插入壹個空行。相同業務邏輯和語義之間不需要插入空行。?
說明:沒有必要插入多行空格進行隔開。?
(四)?OOP?規約?
1.?強制避免通過壹個類的對象引用訪問此類的靜態變量或靜態方法,無謂增加編譯器解析成
本,直接用類名來訪問即可。?
2.?強制所有的覆寫方法,必須加@Override?註解。?
反例:getObject()與?get0bject()的問題。壹個是字母的?O,壹個是數字的?0,加@Override
可以準確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進行修改,其實現類會馬上編
譯報錯。?
3.?強制相同參數類型,相同業務含義,才可以使用?Java?的可變參數,避免使用?Object。?
說明:可變參數必須放置在參數列表的最後。(提倡同學們盡量不用可變參數編程)?
正例:public?User?getUsers(String?type,?Integer...?ids)?
4.?強制外部正在調用或者二方庫依賴的接口,不允許修改方法簽名,避免對接口調用方產生
影響。接口過時必須加@Deprecated?註解,並清晰地說明采用的新接口或者新服務是什麽。?
5.?強制不能使用過時的類或方法。?
說明:java.net.URLDecoder?中的方法?decode(String?encodeStr)?這個方法已經過時,應
該使用雙參數?decode(String?source,?String?encode)。接口提供方既然明確是過時接口,
那麽有義務同時提供新的接口;作為調用方來說,有義務去考證過時方法的新實現是什麽。?
6.?強制Object?的?equals?方法容易拋空指針異常,應使用常量或確定有值的對象來調用
equals。?
正例:?"test".equals(object);?
反例:?object.equals("test");?
說明:推薦使用?java.util.Objects#equals?(JDK7?引入的工具類)?
7.?強制所有的相同類型的包裝類對象之間值的比較,全部使用?equals?方法比較。?
說明:對於?Integer?var?=?在-128?至?127?之間的賦值,Integer?對象是在
IntegerCache.cache?產生,?會復用已有對象,?這個區間內的?Integer?值可以直接使用==進行
判斷,?但是這個區間之外的所有數據,?都會在堆上產生,?並不會復用已有對象,?這是壹個大坑,
推薦使用?equals?方法進行判斷。
8.?關於基本數據類型與包裝數據類型的使用標準如下:?
1)?強制所有的?POJO?類屬性必須使用包裝數據類型。? 2)?強制RPC?方法的返回值和參數必須使用包裝數據類型。? 3)?推薦所有的局部變量使用基本數據類型。? 說明:POJO?類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進行賦值,任何NPE?問題,或者入庫檢查,都由使用者來保證。?
正例:數據庫的查詢結果可能是?null,因為自動拆箱,用基本數據類型接收有?NPE?風險。? 反例:比如顯示成交總額漲跌情況,即正負?x%,x?為基本數據類型,調用的?RPC?服務,調用不成功時,返回的是默認值,頁面顯示:0%,這是不合理的,應該顯示成中劃線-。所以包裝
數據類型的?null?值,能夠表示額外的信息,如:遠程調用失敗,異常退出。?
9.?強制定義?DO/DTO/VO?等?POJO?類時,不要設定任何屬性默認值。?
反例:POJO?類的?gmtCreate?默認值為?new?Date();但是這個屬性在數據提取時並沒有置入具
體值,在更新其它字段時又附帶更新了此字段,導致創建時間被修改成當前時間。?
10.?強制序列化類新增屬性時,請不要修改?serialVersionUID?字段,避免反序列失敗;如
果完全不兼容升級,避免反序列化混亂,那麽請修改?serialVersionUID?值。?
說明:註意?serialVersionUID?不壹致會拋出序列化運行時異常。?
11.?強制構造方法裏面禁止加入任何業務邏輯,如果有初始化邏輯,請放在?init?方法中。?
12.?強制POJO?類必須寫?toString?方法。使用?IDE?的中工具:source>?generate?toString
時,如果繼承了另壹個?POJO?類,註意在前面加壹下?super.toString。?
說明:在方法執行拋出異常時,可以直接調用?POJO?的?toString()方法打印其屬性值,便於排
查問題。?
13.?推薦使用索引訪問用?String?的?split?方法得到的數組時,需做最後壹個分隔符後有無
內容的檢查,否則會有拋?IndexOutOfBoundsException?的風險。?
說明:?
String?str?=?"a,b,c,,";?
String[]?ary?=?str.split(",");?
//預期大於?3,結果是?3?
System.out.println(ary.length);?
14.?推薦當壹個類有多個構造方法,或者多個同名方法,這些方法應該按順序放置在壹起,
便於閱讀。?
15.?推薦?類內方法定義順序依次是:公有方法或保護方法?>?私有方法?>?getter/setter
方法。?
說明:公有方法是類的調用者和維護者最關心的方法,首屏展示最好;保護方法雖然只是子類
關心,也可能是“模板設計模式”下的核心方法;而私有方法外部壹般不需要特別關心,是壹個
黑盒實現;因為方法信息價值較低,所有?Service?和?DAO?的?getter/setter?方法放在類體最
後。?
16.?推薦setter?方法中,參數名稱與類成員變量名稱壹致,this.成員名?=?參數名。在
getter/setter?方法中,盡量不要增加業務邏輯,增加排查問題的難度。?
反例:?
public?Integer?getData()?{?
if?(true)?{?
return?data?+?100;?
}?else?{?
return?data?-?100;?
}?
}?
17.?推薦循環體內,字符串的連接方式,使用?StringBuilder?的?append?方法進行擴展。?
反例:?
String?str?=?"start";?
for?(int?I?=?0;?I?<?100;?i++)?{?
str?=?str?+?"hello";?
}?
說明:反編譯出的字節碼文件顯示每次循環都會?new?出壹個?StringBuilder?對象,然後進行
append?操作,最後通過?toString?方法返回?String?對象,造成內存資源浪費。?
18.?推薦下列情況,聲明成?final?會更有提示性:?
1)?不需要重新賦值的變量,包括類屬性、局部變量。? 2)?對象參數前加?final,表示不允許修改引用的指向。? 3)?類方法確定不允許被重寫。?19.?推薦慎用?Object?的?clone?方法來拷貝對象。?
說明:對象的?clone?方法默認是淺拷貝,若想實現深拷貝需要重寫?clone?方法實現屬性對象
的拷貝。?
20.?推薦類成員與方法訪問控制從嚴:?
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?的成員變量,刪除壹下,不得手心冒點汗嗎?變量像自己的小孩,盡量在自己的視
線內,變量作用域太大,如果無限制的到處跑,那麽妳會擔心的。