我來自.NET背景,現在涉足Java領域。防禦性編程:Java中的指導
目前,我在設計API防禦錯誤輸入方面遇到很大問題。比方說,我有以下代碼(足夠接近):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
但是,此代碼可能會失敗的原因有兩個:
- 用戶通過一個
null
節點。 - 用戶通過一個無效節點,即一個不包含在圖中。
在.NET中,我將拋出一個ArgumentNullException
(而不是NullReferenceException
!)或ArgumentException
分別通過違規參數(node
)爲string
參數的名稱。
Java似乎沒有例外。我意識到我可以更具體,只是拋出最接近描述情況的異常,或者爲特定情況編寫我自己的異常類。
這是最佳做法嗎?或者有類似於.NET中的ArgumentException
的通用類?
在這種情況下檢查null
是否有意義?代碼無論如何都會失敗,異常的堆棧跟蹤將包含上述方法調用。檢查null
似乎是多餘的和過度。當然,堆棧跟蹤將是略微更清潔(因爲它的目標是上述方法,而不是在JRE的HashMap
執行內部檢查)。但是這必須抵消額外的if
聲明的成本,而且,永遠不會出現 - 畢竟,將null
傳遞給上述方法並不是預期的情況,這是一個相當愚蠢的錯誤。期待它是徹頭徹尾的偏執 - 即使我沒有檢查它也會失敗,同樣的例外。
[正如已經在評論中指出的,HashMap.put
實際上允許null
值爲關鍵。所以對null
檢查不一定是多餘這裏]
調用'setTokens(NULL,0)'只會如果你正在使用'Hashtable'或'ConcurrentHashMap'因爲這些不允許'null'鑰匙丟了'NullPointerException'。另一方面,'HashMap'樂於擁有空鍵。 – pjp 2009-09-18 12:56:27
@pjp:感謝您的糾正 - 我曾預料會失敗,因爲'HashMap'需要創建它的參數的散列。我想,還有一個明確檢查的理由。 – 2009-09-18 14:15:16