1. 程式人生 > >阿裏巴巴Java開發手冊上常規的編程命名總結

阿裏巴巴Java開發手冊上常規的編程命名總結

toa 打印 cond 大於 version 適配 false sta ash

阿裏巴巴Java開發手冊上常規的編程命名總結:
1.類名必須駝峰.
例子:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
2.方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須遵從
駝峰形式。
例子:localValue / getHttpMessage() / inputUserId
3.常量命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。
例子:MAX_STOCK_COUNT
4.抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類命 名以它要測試的類的名稱開始,以 Test 結尾
5.包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用 單數形式,但是類名如果有復數含義,類名可以使用復數形式。
例子:應用工具類包名為 com.alibaba.mpp.util、類名為 MessageUtils(此規則參考 spring
的框架結構)
6.設計模式:
推薦如果使用到了設計模式,建議在類名中體現出具體模式。
說明:將設計模式體現在名字中,有利於閱讀者快速理解架構設計思想。
正例:public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
7.接口和實現類的命名有兩套規則:
1)對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務一定是接口,內部
的實現類用 Impl 的後綴與接口區別。
正例:CacheServiceImpl 實現 CacheService 接口
2)推薦 如果是形容能力的接口名稱,取對應的形容詞做接口名(通常是–able 的形式)。
正例:AbstractTranslator 實現 Translatable。
8. 參考枚舉類名建議帶上 Enum 後綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。
說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。
正例:枚舉名字:DealStatusEnum;成員名稱:SUCCESS / UNKOWN_REASON。
9. 各層命名規約:
A) Service/DAO 層方法命名規約
1) 獲取單個對象的方法用 get 做前綴。
2) 獲取多個對象的方法用 list 做前綴,可以用query。
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. 推薦接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔
性,並加上有效的 javadoc 註釋。盡量不要在接口裏定義變量,如果一定要定義變量,肯定是
與接口方法相關,並且是整個應用的基礎常量。
正例:接口方法簽名:void f();
接口基礎常量表示:String COMPANY = "alibaba";
反例:接口方法定義:public abstract void f();
說明:JDK8 中接口允許有默認實現,那麽這個 default 方法,是對所有實現類都有價值的默認實現。
2. 強制.不允許出現任何魔法值(即未經定義的常量)直接出現在代碼中。
反例: String key="Id#taobao_"+tradeId;
cache.put(key, value);
3. long 或者 Long 初始賦值時,必須使用大寫的 L,不能是小寫的 l,小寫容易跟數字 1 混淆,造成誤解。
說明:Long a = 2l; 寫的是數字的 21,還是 Long 型的 2?
4. 不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護。如:緩存 相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。
說明:大而全的常量類,非得 ctrl+f 才定位到修改的常量,不利於理解,也不利於維護
5. 常量的復用層次有五層:跨應用共享常量、應用內共享常量、子工程內共享常量、包
內共享常量、類內共享常量。
1) 跨應用共享常量:放置在二方庫中,通常是 client.jar 中的 const 目錄下。
2) 應用內共享常量:放置在一方庫的 modules 中的 const 目錄下。
反例:易懂變量也要統一定義成應用內共享常量,兩位攻城師在兩個類中分別定義了表示
“是”的變量:
類 A 中:public static final String YES = "yes";
類 B 中:public static final String YES = "y";
A.YES.equals(B.YES),預期是 true,但實際返回為 false,導致產生線上問題。
3) 子工程內部共享常量:即在當前子工程的 const 目錄下。
4) 包內共享常量:即在當前包下單獨的 const 目錄下。
5) 類內共享常量:直接在類內部 private static final 定義。
6. 如果變量值僅在一個範圍內變化用 Enum 類。如果還帶有名稱之外的延伸屬性,必須 使用 Enum 類,下面正例中的數字就是延伸信息,表示星期幾。
正例:public Enum{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5),
SATURDAY(6), SUNDAY(7);}
7.避免通過一個類的對象引用訪問此類的靜態變量或靜態方法,無謂增加編譯器解析成 本,直接用類名來訪問即可。
8.所有的覆寫方法,[email protected]

/* */ 註解。
反例:getObject()與 get0bject()的問題。一個是字母的 O,一個是數字的 0,[email protected]
可以準確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進行修改,其實現類會馬上編
譯報錯
9.相同參數類型,相同業務含義,才可以使用 Java 的可變參數,避免使用 Object。 說明:可變參數必須放置在參數列表的最後。(提倡同學們盡量不用可變參數編程)
正例:public User getUsers(String type, Integer... ids);
10. 對外暴露的接口簽名,原則上不允許修改方法簽名,避免對接口調用方產生影響。接 [email protected]
/* */ 註解,並清晰地說明采用的新接口或者新服務是什麽。
11. 不能使用過時的類或方法
說明:java.net.URLDecoder 中的方法 decode(String encodeStr) 這個方法已經過時,應該
使用雙參數 decode(String source, String encode)。接口提供方既然明確是過時接口,那
麽有義務同時提供新的接口;作為調用方來說,有義務去考證過時方法的新實現是什麽。
12.Object的equals方法容易拋空指針異常,應使用常量或確定有值的對象來調用equals。
正例: "test".equals(object);
object.equals("test");
說明:推薦使用 java.util.Objects#equals (JDK7 引入的工具類)
13.所有的相同類型的包裝類對象之間值的比較,全部使用 equals 方法比較。
說明:對於 Integer var=?在-128 至 127 之間的賦值,Integer 對象是在 IntegerCache.cache
產生,會復用已有對象,這個區間內的 Integer 值可以直接使用==進行判斷,但是這個區間之
外的所有數據,都會在堆上產生,並不會復用已有對象,這是一個大坑,推薦使用 equals 方
法進行判斷。
14.關於基本數據類型與包裝數據類型的使用標準如下:
1) 所有的 POJO 類屬性必須使用包裝數據類型。
2) RPC 方法的返回值和參數必須使用包裝數據類型。
3) 所有的局部變量推薦使用基本數據類型。
說明:POJO 類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進行賦值,任何
NPE 問題,或者入庫檢查,都由使用者來保證。
正例:數據庫的查詢結果可能是 null,因為自動拆箱,用基本數據類型接收有 NPE 風險。
反例:某業務的交易報表上顯示成交總額漲跌情況,即正負 x%,x 為基本數據類型,調用的
RPC 服務,調用不成功時,返回的是默認值,頁面顯示:0%,這是不合理的,應該顯示成中劃
線-。所以包裝數據類型的 null 值,能夠表示額外的信息,如:遠程調用失敗,異常退出。
15.定義 DO/DTO/VO 等 POJO 類時,不要設定任何屬性默認值。 反例:某業務的 DO 的 gmtCreate 默認值為 new Date();但是這個屬性在數據提取時並沒有置
入具體值,在更新其它字段時又附帶更新了此字段,導致創建時間被修改成當前時間。
16.序列化類新增屬性時,請不要修改 serialVersionUID 字段,避免反序列失敗;如果
完全不兼容升級,避免反序列化混亂,那麽請修改 serialVersionUID 值。
說明:註意 serialVersionUID 不一致會拋出序列化運行時異常。
17.構造方法裏面禁止加入任何業務邏輯,如果有初始化邏輯,請放在 init 方法中。
18.POJO 類必須寫 toString 方法。使用工具類 source> generate toString 時,如果繼
承了另一個 POJO 類,註意在前面加一下 super.toString。
說明:在方法執行拋出異常時,可以直接調用 POJO 的 toString()方法打印其屬性值,便於排
查問題。
19.使用索引訪問用 String 的 split 方法得到的數組時,需做最後一個分隔符後有無內 容的檢查,否則會有拋 IndexOutOfBoundsException 的風險。
說明:
String str = "a,b,c,,"; String[] ary = str.split(","); //預期大於 3,結果是 3 System.out.println(ary.length);
20.當一個類有多個構造方法,或者多個同名方法,這些方法應該按順序放置在一起,便
於閱讀。
21. 類內方法定義順序依次是:公有方法或保護方法 > 私有方法 > getter/setter 方
法。
說明:公有方法是類的調用者和維護者最關心的方法,首屏展示最好;保護方法雖然只是子類
關心,也可能是“模板設計模式”下的核心方法;而私有方法外部一般不需要特別關心,是一
個黑盒實現;因為方法信息價值較低,所有 Service 和 DAO 的 getter/setter 方法放在類體最
後。

22.setter 方法中,參數名稱與類成員變量名稱一致,this.成員名=參數名。在 getter/setter 方法中,盡量不要增加業務邏輯,增加排查問題難度。
反例:
public Integer getData(){ if(true) { return data + 100; } else { return data - 100; } }
23.循環體內,字符串的聯接方式,使用 StringBuilder 的 append 方法進行擴展。
反例:
String str = "start"; for(int i=0; i<100; i++){ str = str + "hello"; } 說明:反編譯出的字節碼文件顯示每次循環都會 new 出一個 StringBuilder 對象,然後進行
append 操作,最後通過 toString 方法返回 String 對象,造成內存資源浪費。
24.final 可提高程序響應效率,聲明成 final 的情況:
1) 不需要重新賦值的變量,包括類屬性、局部變量。
2) 對象參數前加 final,表示不允許修改引用的指向。
3) 類方法確定不允許被重寫。
25.慎用 Object 的 clone 方法來拷貝對象。
對象的 clone 方法默認是淺拷貝,若想實現深拷貝需要重寫 clone 方法實現屬性對象的
拷貝。
26.類成員與方法訪問控制從嚴:
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 的成員變量,刪除一下,不得手心冒點汗嗎?變量像自己的小孩,盡量在自己的視
線內,變量作用域太大,如果無限制的到處跑,那麽你會擔心的。
27.Map/Set 的 key 為自定義對象時,必須重寫 hashCode 和 equals。 正例:String 重寫了 hashCode 和 equals 方法,所以我們可以非常愉快地使用 String 對象作
為 key 來使用。
28.ArrayList 的 subList 結果不可強轉成 ArrayList,否則會拋出 ClassCastException 異常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ;
說明:subList 返回的是 ArrayList 的內部類 SubList,並不是 ArrayList ,而是 ArrayList
的一個視圖,對於 SubList 子列表的所有操作最終會反映到原列表上。
29.在 subList 場景中,高度註意對原集合元素個數的修改,會導致子列表的遍歷、增加、 刪除均產生 ConcurrentModificationException 異常。
30.使用集合轉數組的方法,必須使用集合的 toArray(T[] array),傳入的是類型完全 一樣的數組,大小就是 list.size()。
反例:直接使用 toArray 無參方法存在問題,此方法返回值只能是 Object[]類,若強轉其它
類型數組將出現 ClassCastException 錯誤。
31.使用工具類Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法, 它的 add/remove/clear 方法會拋出 UnsupportedOperationException 異常。
說明:asList 的返回對象是一個 Arrays 內部類,並沒有實現集合的修改方法。Arrays.asList
體現的是適配器模式,只是轉換接口,後臺的數據仍是數組。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一種情況:list.add("c"); 運行時異常。
第二種情況:str[0]= "gujin"; 那麽 list.get(0)也會隨之修改。
32. 泛型通配符<? extends T>來接收返回的數據,此寫法的泛型集合不能使用 add 方法。
說明:蘋果裝箱後返回一個<? extends Fruits>對象,此對象就不能往裏加任何水果,包括蘋
果。
33.不要在 foreach 循環裏進行元素的 remove/add 操作。remove 元素請使用 Iterator 方式,如果並發操作,需要對 Iterator 對象加鎖。
反例:
List<String> a = new ArrayList<String>(); a.add("1"); a.add("2"); for (String temp : a) { if("1".equals(temp)){ a.remove(temp); } }
說明:這個例子的執行結果會出乎大家的意料,那麽試一下把“1”換成“2”,會是同樣的結
果嗎?
警告:
1.中括號是數組類型的一部分,數組定義如下:String[] args,反例:請勿使用 String args[]的方式來定義
2.POJO 類中的任何布爾類型的變量,都不要加 is,否則部分框架解析會引起序列化錯誤。
反例:定義為基本數據類型 boolean isSuccess;的屬性,它的方法也是 isSuccess(),RPC
框架在反向解析的時候,“以為”對應的屬性名稱是 success,導致屬性獲取不到,進而拋出
異常。
3.杜絕完全不規範的縮寫,避免望文不知義。
反例:<某業務代碼>AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成
condi,此類隨意縮寫嚴重降低了代碼的可閱讀性。

阿裏巴巴Java開發手冊上常規的編程命名總結