Java – 你的 Java 程式碼有這些壞味道嗎?

列舉一些 Java 開發中常見的「不良實踐」,來源於程式碼掃描(//github.com/pmd/pmd),和諸君一起學習參考:

1 – 關閉資源

CloseResource: Ensure that resources like this FileInputStream object are closed after use.

確保 FileInputStream、HttpClient 之類的對象在使用後被及時關閉。

JDK 1.8 開始建議使用 try-with-resource 關閉資源,因為對於多個資源或異常的捕獲中,try-finally 可能丟失掉前面的異常,而 try-with-resource 會保留第一個異常,並把後續的異常作為Suppressed exceptions,可通過 getSuppressed() 返回的數組來檢驗。

try-with-resource 示例:

try (FileReader fileReader = new FileReader(filePath);
    BufferedReader bfReader = new BufferedReader(fileReader)) {
    // do something
}

2 – 松耦合

LooseCoupling: Avoid using implementation types like ‘ArrayList’, use the interface instead.

避免使用具體的實現類型,比如「ArrayList」,而是使用它們的介面,比如:

// 這種方法不好:
public ArrayList<String> getList() {
    ArrayList<String> list = new ArrayList<String>();
    // do something
    return list;
}

// 建議這樣用:
public List<String> getList() {
    List<String> list = new ArrayList<String>();
    // do something
    return list;
}

第二種寫法的優點是,這個方法的調用者不必關注方法內部到底使用了哪個 List<String> 的具體實現,並且就算方法內部的實現發生了變化,調用方也不需要修改自己的程式碼。

3 – 避免捕獲NPE

AvoidCatchingNPE – Avoid catching NullPointerException, consider removing the cause of the NPE.

避免捕獲空指針異常,考慮刪除相關的捕獲語句,並在程式碼中進行空引用的檢查。

程式在運行期拋出 NullPointException 異常,表明存在一個對空指針的解引用,這類問題應該在程式碼中解決。

通過捕獲 NullPointException 異常而不對根本原因進行處理是不合適的:

1)捕獲 NullPointException 而不是作簡單的空引用檢查,在性能上要付出更大的代價;

2)當 try 程式段中多個表達式都有可能拋出 NullPointException 時,無法正確判斷異常的拋出位置;

3)程式拋出 NullPointException 異常很少會處於正常的可用狀態。

4 – 使用 equals() 方法來比較 String 類型

UseEqualsToCompareStrings – Use equals() to compare strings instead of ‘==’ or ‘!=’.

使用 equals() 方法對 String 類型進行比較,而不是用 「==」 或 「!=」。

這是為了防止比較的對象是通過 new String(“”) 構造的,== 比較的是對象的地址,要注意這點。

5 – 使用 「==」 判斷實例是否為 null

EqualsNull – Avoid using equals() to compare against null.

使用 「==」 判斷實例是否為 null ,如:str == null,而不是 str.equals(null)

6 – 避免列印堆棧資訊

AvoidPrintStackTrace – Avoid printStackTrace(), use a logger call instead.

避免使用 printStackTrace() 方法直接列印堆棧,而是要使用日誌框架列印堆棧資訊。

7 – Integer 類型的初始化

IntegerInstantiation – Avoid instantiating Integer objects. Call Integer.valueOf() instead.

避免通過 new Integer(param) 直接創造 Integer 對象,推薦用:Integer.valueOf(param) 的方法來創建。

如果是 String 類型的參數,推薦用 Integer.parseInt() 方法,解析生成對應的數值類型,更高效。

其他類型(比如 Boolean\Long、 Double)的解析,修改方式和 Integer 相同。

8 – Boolean 類型的初始化

BooleanInstantiation – Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead.

避免創建 Bool 類型的對象,比如 new Boolean(false),建議使用全局的 Boolean 實例。

由於 Boolean 類型就只有 1 / 0 兩種狀態,因此建議通過 Boolean.TRUEBoolean.FALSE,或 Boolean.valueOf() 來使用。

參考資料

//github.com/pmd/pmd

版權聲明

作者:瘦風(//healchow.com)

出處:部落格園-瘦風的南牆(//www.cnblogs.com/shoufeng)

感謝閱讀,公眾號 「瘦風的南牆」 ,手機端閱讀更佳,還有其他福利和心得輸出,歡迎掃碼關注🤝

本文版權歸部落客所有,歡迎轉載,但 [必須在頁面明顯位置標明原文鏈接],否則部落客保留追究相關人士法律責任的權利。