閱讀55 返回首頁    go 技術社區[雲棲]


《數據結構與抽象:Java語言描述(原書第4版)》一2.1.4 讓實現安全

本節書摘來華章計算機《數據結構與抽象:Java語言描述(原書第4版)》一書中的第2章 ,第2.1節,[美]弗蘭克M.卡拉諾(Frank M. Carrano) 蒂莫西M.亨利(Timothy M. Henry) 著 羅得島大學  新英格蘭理工學院 辛運幃 饒一梅 譯 更多章節內容可以訪問雲棲社區“華章計算機”公眾號查看。

2.1.4 讓實現安全

鑒於當今黑客及對重要軟件係統未經授權入侵的現實情況,程序員必須在代碼中添加安全措施,以使程序對使用者是安全的。雖然Java為你管理內存,檢查數組下標的合法性,且是類型安全的,但一個錯誤會使你的代碼易受攻擊。實現ADT時應該時刻銘記安全性,盡管在已有的代碼中增加安全機製可能是困難的。

注:你可以在程序中檢查可能出現的錯誤來練習有安全機製的程序設計(fail-safe programming)。安全可靠程序設計(safe and secure programming)通過驗證輸入給方法的數據和參數的合法性,消除方法的副作用,對客戶和使用者的行為不做任何假設,來擴展有安全機製的程序設計的概念。
安全說明:保護ADT實現的完整性
當實現一個ADT時,必須問自己的兩個問題是

  • 如果構造方法沒有完全執行,那麼可能會發生什麼?例如,構造方法可能在完成初始化之前就拋出一個異常或錯誤。但是入侵者可能捕獲異常或錯誤,並試圖使用部分初始化的對象。
  • 如果客戶試圖創建一個其容量超出給定範圍的包,那麼可能會發生什麼? 如果這兩個動作可能導致問題,則我們必須阻止它們。 對於類ArrayBag,我們想防範前麵安全說明中所描述的兩種情形。現在開始細化ArrayBag的不完整的實現,在類中增加下列兩個數據域,以使代碼更安全: image

這兩個修改都涉及構造方法。因為默認的構造方法調用帶參數的構造方法,所以僅修改後者就足夠了。為確保客戶不能創建太大的包,構造方法應該檢查客戶所需包的容量與MAX_CAPACITY值。如果需要的容量太大,則構造方法可以拋出一個異常。
如果所需的容量處在允許範圍內,則ArrayBag的構造方法為什麼還不能正確完成呢?因為內存不足可能導致分配數組失敗。這樣一個事件會導致錯誤OutOfMemoryError。一般地,客戶將這個錯誤看作致命事件。黑客可能捕獲這個錯誤(就像你捕獲異常一樣),並試圖使用部分初始化的對象。為防止這種情況,類的每個重要方法在執行其操作之前都可以檢查域initialized的狀態。這樣,畸形對象就不會再有動作。對於正確初始化的對象,構造方法將把域initialized置為真。
下麵是修改後的構造方法。
image

注意,構造方法在成功完成其他任務後,最後一個動作是將initialized賦值為真。還應注意,IllegalStateException是標準運行時異常。
下麵來看看如何使用initialized。
在數組bag已成功分配的基礎上,ArrayBag中的任何公有方法在繼續執行之前都應該確保數據域initialized的值為真。如果initialized為假,這樣的方法可以拋出一個異常。例如,可以如下所示修改方法add。
image
image

注:異常SecurityException和IllegalStateException都是包java.lang中的標準運行時異常。因此,不需要import語句。

因為我們將在多個方法中檢查initialized,所以為避免代碼重複定義下列私有方法。
image

方法add可以修改為:
image

應該以相同的方式修改核心方法toArray,因為它用到了ArrayBag的數據域bag。

安全說明:你所熟知的編寫Java代碼的某些常見準則,實際上增加了代碼的安全性。這些準則是:

  • 將類的大多數數據域聲明為私有的,如果不是全部。任何公有數據域都應該是靜態和終態的,且有常量值。
  • 避免那些掩蓋代碼安全性的所謂聰明的邏輯。
  • 避免重複代碼。相反,將這樣的代碼封裝為一個可供其他方法調用的私有方法。
  • 當構造方法調用一個方法時,確保這個方法不能被重寫。

安全說明:終態類。注意,我們將ArrayBag聲明為一個終態類。因此,不會有從ArrayBag派生的其他類,即ArrayBag不能是另一個類的父類或基類。終態類比非終態類更安全,因為程序員不能使用繼承來改變它的行為。稍後我們將細化這個方法,定義終態方法而不是整個類。

最後更新:2017-06-26 17:02:21

  上一篇:go  《數據結構與抽象:Java語言描述(原書第4版)》一2.1.5 測試核心方法
  下一篇:go  《數據結構與抽象:Java語言描述(原書第4版)》一2.1.3 實現核心方法