天天看點

《Java安全編碼标準》一3.2 DCL01-J不要重用Java标準庫的已經公開的辨別

不要重用那些在java标準庫中已經使用過的公共的辨別、公共的工具類、接口或者包。

當一個程式員使用和公開類相同的名字時,如vector對後來的維護者來說,他可能不知道這個辨別并不是指?java.util.vector?,并且可能會無意地使用這個自定義的vector類而不是原有的java.util.vector類。使得這個自定義的?vector會遮蔽java.util.vector類,正如在jls的6.3.2節中提到的那樣。進而會導緻不可預期的程式行為。

良好定義的import語句可以解決這個問題。然而,當重用的命名定義是從其他包中導入時,使用type-import-on-demand declaration(詳細參見jls的7.5.2節“type-import-on-demand declaration”[jls 2005])會将程式員弄糊塗,因為他需要确定哪一個定義是想要的。另外,因為我們通常會使ide來自動包括import語句,是以一種常見的操作是在編寫代碼後才生成這些import語句,但這種做法容易導緻錯誤。在java包含的import引用路徑中,如果在預期的類出現之前出現了一個自定義的類,那麼不會進一步搜尋,這樣就會毫無知覺地使用了錯誤的類。

這個不符合規則的代碼實作了一個類,這個類重用了java.util.vector 的名稱。它在isempty()中使用了一個不同的條件判斷,嘗試通過重寫java.util.vector中對應的方法來達到與遺留代碼接口的目的。如果維護者混淆了這個isempty()和java.util.vector. isempty(),就會出現不可預知的行為。

這個符合規則的方案為這個類使用了不同的名字,防止這個類作為任何潛在的java标準類庫中的類名稱的遮蔽情況出現。

當程式員和開發團隊可以控制那些被模仿的原始類,更好的方法就是改變對它們的設計政策,這些政策可以根據bloch的《effective java》[bloch 2008]一書中第16條,更傾向于接口而不是抽象類的方法來實作。将原始類改變成接口,這可以讓myvector類得以通過聲明它是我們假設的接口vector?的實作。這可以讓使用myvector的代碼與使用原始vector實作的代碼互相相容。

重用公有的辨別會降低代碼的可讀性和可維護性。

《Java安全編碼标準》一3.2 DCL01-J不要重用Java标準庫的已經公開的辨別

自動化檢測 對于重用了java标準類庫中公共類和接口的名字的問題,它們可以被自動檢測工具很容易地檢測到。

《Java安全編碼标準》一3.2 DCL01-J不要重用Java标準庫的已經公開的辨別
《Java安全編碼标準》一3.2 DCL01-J不要重用Java标準庫的已經公開的辨別