Java開發手冊

開發手冊

名詞解釋

POJO(Plain Ordinary Java Object):專指setter / getter / toString的簡單類,包括:DO / DTO / BO / VOjava

GAV(GroupId ArtifactctId Version):Maven座標,用來惟一標識jar包git

OOP(Object Oriented Programming):泛指類、對象的基本編程處理方式github

ORM(Object Relation Mapper):對象關係映射、對象領域模型與底層數據之間的轉換數據庫

NPE(java.lang.NullPointerException):空指針異常編程

SOA(Service-Oriented Architecture):面向服務架構,根據需求經過網絡對鬆散耦合的粗粒度應用軟件進行分佈式部署、組合使用設計模式

一方庫:子項目模塊依賴的庫數組

二方庫:Maven依賴的庫網絡

三方庫:公司以外開源的庫架構

IDE檢測插件:github.com/alibaba/p3c併發

命名風格

  1. 命名不能如下劃線或美圓符號開始,也不能如下劃線或美圓符號結束。 反例:_name $name name_ name$
  2. 禁止拼音與英文混合方式,更不容許使用中文。通用名稱,但是同英文:alibaba\taobao\youku\hangzhou
  3. 類名使用UpperCamelCase(首字母大寫)風格,但DO、BO、DTO、VO、AO、PO等情形例外
  4. 方法名、參數名、成員變量、局部變量統一使用lowerCamelCase風格,必須遵照駝峯。例如:localValue/getHttpMessage()
  5. 常量命名所有大寫,單詞下劃線分開,力求語義表達完整
  6. 抽象類命名使用Abstract或Base開頭。異常類命名使用Exception結尾。測試類命名以它要測試的類名開始,Test結尾。
  7. 類型與中括號之間無空格相連定義數組。例如:int[] arrayDemo;
  8. POJO類中布爾類型的變量都不要加is前綴。不然部分框架解析會引發序列化錯誤
  9. 包名統一使用小寫,點分隔符之間僅有一個天然語義的英文單詞。包名統一使用單數形式,但類名若是有複數含義,則類名可使用複數形式。例如:com.alibaba.ai.util。類名MessageUtils
  10. 避免在子父類的成員變量之間或不一樣代碼塊的局部變量之間採用徹底相同的命名方式,使其下降可讀性
  11. 杜絕徹底不規範的縮寫,避免詞義不達標:例如:AbstractClass 縮寫 AbsClass
  12. 任何自定義編程元素在命名時,使用盡可能完整的單詞組合來表達其意。例如:對某個對象引用的volatile字段進行原子,AtomicReferenceFiledUpdater
  13. 常量與變量命名時,表達類型的名詞放在詞尾,以提高辨識度。例如:startTime\workQueue\nameList
  14. 若是模塊、接口、類、方法使用設計模式,應該在命名時體現出具體模式。例如:LoginProxy、OrderFactory、ResourceObserver
  15. 接口類中的方法和屬性不要加任何修飾符號(public 也不要加)保持代碼的簡潔性,並加上有效的Javadoc註釋。儘可能不要在接口裏定義變量,若是必定要定義變量,必須時與接口方法相關的,而且是整個應用的基礎常量。
  16. 接口和實現類的命名有兩套規則:
    1. 對於Service和DAO類,基於SOA的理念暴露出來的服務必定是接口,內部的實現類用Impl後綴與接口區別。例如:CacheServiceImpl 實現 CacheService接口
    2. 若是是形容能力的接口名稱,取對應的形容詞爲接口名(一般是-able的形式)。例如:AbstractTranslator 實現 Translatable
  17. 枚舉類名建議帶上Enum後綴,成員名稱須要全大寫,單詞下劃線分割。例如:ProcessStatusEnum、SUCCESS
  18. 各層命名規約:
    1. Service/DAO層方法命名規約以下。
    • 獲取單個對象的方法用get做爲前綴
    • 獲取多個對象的方法用list做爲前綴,複數結尾,如listObjects。
    • 獲取統計值的方法用count做爲前綴
    • 插入的方法用save / insert做爲前綴
    • 刪除的方法用remove / delete 做爲前綴
    • 修改的方法用update做爲前綴
    1. 領域模型命名規約以下
    • 數據對象:xxxDO,xxx爲數據表名
    • 數據傳輸對象:xxxDTO,xxx爲業務領域相關名稱
    • 展現對象:xxxVO, xxx通常爲網頁名稱
    • POJO是統稱,禁止命名

常量定義

  1. 不容許任何魔法值(未經預先定義的常量)直接出如今代碼中
  2. long或者Long初始化賦值時,數值後使用大寫的L,不能是小寫。
  3. 不要使用一個常量類維護全部常量,要按照常量功能進行歸類,分開維護
  4. 常量的複用層次有5層:跨應用共享常量、應用內共享常量、子工程內共享常量、包內共享常量、類內共享常量
    1. 跨應用共享:放置在二方庫中,一般時client.jar中的constant目錄下
    2. 應用內共享:放置在一方庫中,一般實在子模塊中的constant目錄下
    3. 子工程內共享:當前子工程的constant目錄下
    4. 包內共享:當前包下單獨的constant目錄下
    5. 類內共享:provate static final
  5. 若是變量值僅在一個範圍內變化,則用enum類型來定義。例以下面代碼

代碼格式

  1. 大括號的使用約定,若是大括號內爲空,則簡潔地寫成{}便可,大括號中間無須換行和空格。若是是非空代碼塊,則
    1. 左大括號前不換行
    2. 左大括號後換行
    3. 右大括號前換行
    4. 右大括號後還有else等代碼不換行。終止的話必須換行
  2. 左小括號和字符間不出現空格,右小括號和字符間也不出現空格。左大括號前須要加空格
  3. if / for / while / switch / do 等保留關鍵字與括號之間必須加空格
  4. 任何二目、三目運算符左右兩邊都要加空格
  5. 採用4個空格縮進,禁止使用Tab控制符
  6. 註釋的雙斜線與註釋內容之間有且僅有一個空格
  7. 進行類型強制轉換時,右括號與強制轉換值之間不須要任何空格隔開
  8. 單行字符數不超過120個,超出則須要換行,換行時遵循以下原則
    1. 第二行相對第一行縮進4個空格,第三行開始再也不持續縮進
    2. 運算符與下文一塊兒換行
    3. 方法調用的點符號與下文一塊兒換行
    4. 方法調用中的多個參數須要換行時,在逗號後進行
    5. 括號前不要換行
  9. 方法參數在定義和傳入時,多個參數逗號後邊必須加空格
  10. IDE的text file encoding設置爲UTF-8,IDE中文件的換行符使用UNIX格式,不要使用Windows格式
  11. 沒有必要增長若干空格來使變量的賦值等號與上一行對應位置的等號對齊
  12. 單個方法的總行數不超過80行
  13. 不一樣邏輯、不一樣語義、不一樣業務的代碼之間插入一個空行來分隔開,以提高可讀性

OOP規約

  1. 避免經過一個類的對象引用方法此類的靜態變量或靜態方法。直接用類名來訪問便可
  2. 全部的覆寫方法,必須加@Override註解
  3. 相同參數類型,相同業務含義,纔可使用Java的可變參數,避免使用Object
  4. 對外部正在調用或二方庫依賴的接口,不容許修改方法簽名,以免對接口調用方產生影響。若接口過期,必須加@Deprecated註解,並告知新接口或服務是什麼
  5. 不能使用過期的類或方法
  6. Object的equals方法容易拋空指針異常,應使用常量或肯定有值的對象來調用equals
  7. 全部整型包裝類對象之間值的比較,所有使用equals方法
  8. 浮點數之間的等值判斷,基本數據類型不能用 == 進行比較,包括數據類型不能用equals方法進行判斷。須要指定一個偏差範圍,兩個浮點數的差值在此範圍以內則認爲是相等的。
    1. 例如:float diff = 1e-6f;   Math.abs(a-b) < diff
    2. BigDecimal a,BigDecimal b; a.equalsb
  9. 定義數據對象DO類時,屬性類型要與數據庫字段類型相匹配。例如:數據庫字段bigint類型必須與類屬性Long類型相對應
  10. 禁止使用構造方法BigDecimal(double)的方式把 double 值轉換爲BigDecimal對象。會存在損失精度的風險。推薦:入參爲String的構造、或BigDecimal.valueOf
  11. 基本數據類型與包裝數據類型的使用標準以下
    1. 全部的POJO類屬性必須使用包裝數據類型。數據庫查詢結果可能爲null,由於自動拆箱,基本數據類型有NPE風險
    2. RPC方法的返回值和參數必須使用包裝數據類型
    3. 全部的局部變量使用基本數據類型。
  12. 定義DO/DTO/VO等POJO類時,不要設定任何屬性默認值
  13. 序列化類新增屬性時,請不要修改serialVersionUID字段,以免反序列化失敗;若是不兼容升級,避免反序列化混亂,須要修改
  14. 構造方法禁止加入任何業務邏輯,若是有初始化邏輯,放在init方法中
  15. POJO類必須寫toString方法。若是繼承另外一個POJO類,注意添加super.toString()。解釋:當方法拋出異常時,能夠直接調用POJO的toString方法打印其屬性值,便於排查
  16. 禁止在POJO類中,同時存在對應屬性xxx的isxxx() 和 getXXX() 方法。框架在調用屬性的提取方法時,並不能肯定哪一個方法優先調用到
  17. 當使用索引訪問String的split方法獲得的數組時,須要在最後一個分隔符後作有無內容的檢查。不然會拋出IndexOutOfBoundsException的風險
  18. 當一個類有多個構造方法,或多個同名方式時,應該按照順序放置在一塊兒
  19. 類內方法定義順序:公共方法或保護方法 > 私有方法 > getter / setter
  20. 在setter方法中,參數名稱與類成員變量名稱一致,this.成員名 = 參數名。不要增長業務邏輯,不然會增長排查問題的難度
  21. 循環體內,字符串的鏈接方式使用StringBuilder的append方法進行擴展。不要使用字符串
  22. final能夠聲明類、成員變量、本地方法及本地變量。推薦使用狀況以下
    1. 不容許被繼承的類
    2. 不容許修改引用的域對象
    3. 不容許被重寫的方法
    4. 不容許運行過程當中從新賦值的局部變量
    5. 避免上下文重複使用一個變量,使用final描述能夠強制從新定義一個變量,方便更好地進行重構
  23. 慎用Object的clone方法來拷貝對象。由於是淺拷貝
  24. 類成員與方法訪問控制從嚴
    1. 若是不容許外部直接經過new來建立對象,那麼構造必須限制private
    2. 工具類不容許有Public或default構造方法
    3. 非靜態成員變量而且與子類共享,必須限制爲protected
    4. 非靜態成員變量而且僅在本類使用,必須限制爲private
    5. 靜態成員變量若是僅在本類使用,必須限制爲private
    6. 如果static成員變量,必須考慮是否爲final
    7. 類成員方法只供類內部調用,必須限制爲private
    8. 類成員方法只對繼承類公開,限制爲protected

集合處理

  1.  關於hashCode和equals的處理,遵循以下規則:
    1. 只要重寫equals,就必須重寫hashCode
    2. 由於Set存儲的是不重複的對象,依據hashCode和euqals進行判斷,因此Set存儲的對象必須重寫這兩種方法
    3. 若是自定義對象做爲Map的鍵,那麼必須重寫hashCode和equals
  2. 使用Map的方法keySet()/values()/entrySet(),返回集合對象時,不能夠對其添加元素,不然回拋出異常
  3. Collections類返回的對象,如emptyList()/singletonList()等都是immutable list,不能夠對其添加或者刪除元素
  4. ArrayList的subList結果不可強轉成ArrayList,不然回拋出異常。解釋:subList返回的時ArrayList的內部類,並非ArrayList
  5. 在subList場景中,高度注意對原集合元素的增長或刪除,均會致使子列表的遍歷、增長、刪除均產生異常
  6. 使用集合轉數組的方式,必須使用集合的toArray(T[] array),傳入的類型是徹底同樣的數組,大小就是list.size()。
  7. 在使用Collection接口任何實現類的addAll()方法時,都要對輸入的集合參數進行NPE判斷
  8. 使用工具類Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法,它的add / remove / clear方法會拋出異常。
    1. asList的返回對象是一個Arrays內部類,並無實現集合的修改方法。Arrays.asList體現的是適配器模式,只是轉換接口,後臺的數據還是數組
  9. 泛型通配符<? extends T>用來接收返回的數據,此寫法的泛型集合不能使用add方法,而<? super T> 不能使用get方法,由於其做爲接口調用賦值很容易出錯
    1. PECS(Producer Extends Consumer Super)原則:第一,頻繁往外讀取內容的,適用於<? extends T>;第二,常常往裏插入的,適用於<? super T>
  10. 無泛型限制定義的集合賦值給泛型限制的集合時,當使用集合元素時,須要進行性instanceof判斷,避免拋出ClassCastException異常
  11. 不要再foreach循環裏進行元素的remove / add操做。remove元素請使用Iterator方式,若是併發操做,須要對Iterator對象加鎖。
  12. Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()){
        String item = iterator.next();
        if (刪除元素的條件){
            iterator.remove();
        }
    }        

 

 

 

 

 

 

 

相關文章
相關標籤/搜索