---恢復內容開始---html
【強制】POJO類中布爾類型的變量,都不要加is,不然部分框架解析會引發序列化錯誤。反例:定義爲基本數據類型boolean isSuccess;的屬性,它的方法也是isSuccess(),RPC框架在反向解析的時候,「覺得」對應的屬性名稱是success,致使屬性獲取不到,進而拋出異常。java
【強制】包名統一使用小寫,點分隔符之間有且僅有一個天然語義的英語單詞。包名統一使用單數形式,可是類名若是有複數含義,類名可使用複數形式。
正例:應用工具類包名爲com.alibaba.open.util、類名爲MessageUtils(此規則參考spring的框架結構)spring
【推薦】接口類中的方法和屬性不要加任何修飾符號(public也不要加),保持代碼的簡潔性,並加上有效的Javadoc註釋。儘可能不要在接口裏定義變量,若是必定要定義變量,確定是與接口方法相關,而且是整個應用的基礎常量。
正例:接口方法簽名:void f();設計模式
接口基礎常量表示:String COMPANY= "alibaba";
反例:接口方法定義:public abstract void f();
說明:JDK8中接口容許有默認實現,那麼這個default方法,是對全部實現類都有價值的默認實現。緩存
接口和實現類的命名有兩套規則:
1)【強制】對於Service和DAO類,基於SOA的理念,暴露出來的服務必定是接口,內部安全
的實現類用Impl的後綴與接口區別。正例:CacheServiceImpl實現CacheService接口。併發
2)【推薦】 若是是形容能力的接口名稱,取對應的形容詞作接口名(一般是–able的形式)。正例:AbstractTranslator實現Translatable。app
【參考】各層命名規約:
A) Service/DAO層方法命名規約框架
1)獲取單個對象的方法用get作前綴。
2)獲取多個對象的方法用list作前綴。
3)獲取統計值的方法用count作前綴。
4)插入的方法用save(推薦)或insert作前綴。dom
5)刪除的方法用remove(推薦)或delete作前綴。
6)修改的方法用update作前綴。
B)領域模型命名規約
1)數據對象:xxxDO,xxx即爲數據表名。
2)數據傳輸對象:xxxDTO,xxx爲業務領域相關的名稱。
3)展現對象:xxxVO,xxx通常爲網頁名稱。
常量定義
不容許出現任何魔法值(即未經定義的常量)直接出如今代碼中。反例:String key="Id#taobao_"+tradeId;
cache.put(key,value);
4)POJO是DO/DTO/BO/VO的統稱,禁止命名成xxxPOJO。
【推薦】不要使用一個常量類維護全部常量,應該按常量功能進行歸類,分開維護。如:緩存相關的常量放在類:CacheConsts下;系統配置相關的常量放在類:ConfigConsts下。說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利於理解和維護。
【推薦】常量的複用層次有五層:跨應用共享常量、應用內共享常量、子工程內共享常量、包內共享常量、類內共享常量。
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,致使產生線上問題。
OOP規約
【強制】避免經過一個類的對象引用訪問此類的靜態變量或靜態方法,無謂增長編譯器解析成
本,直接用類名來訪問便可。
【強制】對外暴露的接口簽名,原則上不容許修改方法簽名,避免對接口調用方產生影響。接口過期必須加@Deprecated註解,並清晰地說明採用的新接口或者新服務是什麼。
【強制】Object的 equals方法容易拋空指針異常,應使用常量或肯定有值的對象來調用equals。
正例:"test".equals(object);
反例:object.equals("test");說明:推薦使用java.util.Objects#equals(JDK7引入的工具類)
【強制】全部的相同類型的包裝類對象之間值的比較,所有使用equals 方法比較。說明:對於Integer var=?在-128至127之間的賦值,Integer對象是在IntegerCache.cache產生,會複用已有對象,這個區間內的 Integer值能夠直接使用==進行判斷,可是這個區間以外的全部數據,都會在堆上產生,並不會複用已有對象,這是一個大坑,推薦使用equals 方法進行判斷。
【強制】關於基本數據類型與包裝數據類型的使用標準以下:
1)全部的POJO類屬性必須使用包裝數據類型。
2)RPC方法的返回值和參數必須使用包裝數據類型。
3)全部的局部變量【推薦】使用基本數據類型。
說明:POJO類屬性沒有初值是提醒使用者在須要使用時,必須本身顯式地進行賦值,任何
NPE問題,或者入庫檢查,都由使用者來保證。
【強制】構造方法裏面禁止加入任何業務邏輯,若是有初始化邏輯,請放在init方法中。
【強制】POJO類必須寫toString方法。使用IDE的中工具:source>generate toString時,若是繼承了另外一個POJO類,注意在前面加一下super.toString。說明:在方法執行拋出異常時,能夠直接調用POJO的toString()方法打印其屬性值,便於排查問題。
類內方法定義順序依次是:公有方法或保護方法>私有方法>getter/setter
方法。說明:公有方法是類的調用者和維護者最關心的方法,首屏展現最好;保護方法雖然只是子類關心,也多是「模板設計模式」下的核心方法;而私有方法外部通常不須要特別關心,是一個黑盒實現;由於方法信息價值較低,全部Service和DAO的getter/setter方法放在類體最後。
【推薦】循環體內,字符串的聯接方式,使用StringBuilder的append方法進行擴展。
反例:
String str = "start";for(int i=0; i<100; i++){
str = str + "hello";}
說明:反編譯出的字節碼文件顯示每次循環都會new出一個StringBuilder對象,而後進行append操做,最後經過toString方法返回String對象,形成內存資源浪費。
【推薦】final可提升程序響應效率,聲明成final的狀況:1)不須要從新賦值的變量,包括類屬性、局部變量。
2)對象參數前加final,表示不容許修改引用的指向。
3)類方法肯定不容許被重寫。
【推薦】類成員與方法訪問控制從嚴:
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的成員變量,刪除一下,不得手心冒點汗嗎?變量像本身的小孩,儘可能在本身的視線內,變量做用域太大,若是無限制的處處跑,那麼你會擔憂的。
(五)集合處理
【強制】關於hashCode和equals的處理,遵循以下規則:
1) 只要重寫equals,就必須重寫hashCode。
2) 由於Set存儲的是不重複的對象,依據hashCode和equals進行判斷,因此Set存儲的對象必須重寫這兩個方法。
3) 若是自定義對象作爲Map的鍵,那麼必須重寫hashCode和equals。
正例:String重寫了hashCode和equals方法,因此咱們能夠很是愉快地使用String對象做爲key來使用。
【強制】ArrayList的subList結果不可強轉成ArrayList,不然會拋出ClassCastException異常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ;說明:subList返回的是 ArrayList的內部類 SubList,並非ArrayList ,而是ArrayList的一個視圖,對於SubList子列表的全部操做最終會反映到原列表上。
【強制】 在 subList場景中,高度注意對原集合元素個數的修改,會致使子列表的遍歷、增長、刪除均產生ConcurrentModificationException異常。
【強制】泛型通配符<?extends T>來接收返回的數據,此寫法的泛型集合不能使用add方法。
說明:蘋果裝箱後返回一個<?extends Fruits>對象,此對象就不能往裏加任何水果,包括蘋果。
【強制】不要在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);
}}
詳細解釋,請看個人另外一篇blog :
http://www.cnblogs.com/AmoryWang-JavaSunny/p/7468324.html
【推薦】高度注意Map類集合K/V能不能存儲null值的狀況,以下表格:
集合類 |
Key |
Value |
Super |
說明 |
Hashtable |
不容許爲null |
不容許爲null |
Dictionary |
線程安全 |
ConcurrentHashMap |
不容許爲null |
不容許爲null |
AbstractMap |
分段鎖技術 |
TreeMap |
不容許爲null |
容許爲null |
AbstractMap |
線程不安全 |
HashMap |
容許爲null |
容許爲null |
AbstractMap |
線程不安全 |
反例:因爲HashMap的干擾,不少人認爲ConcurrentHashMap是能夠置入null值,注意存儲null值時會拋出NPE異常。
【參考】利用Set元素惟一的特性,能夠快速對一個集合進行去重操做,避免使用List的contains方法進行遍歷、對比、去重操做
關於Map的常見問題和相關知識,請看個人另外一篇blog :
http://www.cnblogs.com/AmoryWang-JavaSunny/p/7487373.html
(六)併發處理
1.【強制】獲取單例對象須要保證線程安全,其中的方法也要保證線程安全。
說明:資源驅動類、工具類、單例工廠類都須要注意。
關於建立單例對象,單例模式,詳看個人另一篇blog :