java開發習慣_來自alibaba

---恢復內容開始---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 : 

相關文章
相關標籤/搜索