物件導向程式設計


1. 【強制】避免透過一個類別的物件引用存取此類別的靜態變數或靜態方法,無謂增加編譯器解析成本,直接用類別名稱來存取即可。


2. 【強制】所有的覆寫方法,必須加上@ Override 註解。

反例: getObject() 與 get 0 bject() 的問題。一個是字母的 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 (JDK 7 引入的工具類別)


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 可提高程式回應效率,宣告成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 的成員變量,刪除一下,不得手心冒點汗嗎?變數像自己的小孩,盡量在自己的視線內,變數作用域太大,如果無限制的到處跑,那麼你會擔心的。


#