大部分的方法及 constructor 對於傳入的參數都會有些限制,像是不可傳入 null 或是 index 不可以小於 0,這些限制都需要在文件中清楚說明。在方法的開頭處便進行檢查,讓錯誤及早發現。 若是沒有在開頭處檢查,程式持續往下執行,往往會增加未來除錯的困難度。
如果檢查時,發現傳入的參數有誤,應丟出例外 (exception),並清楚的說明原因。對於 public 及 protected 方法,使用 Javadoc 中 @throws 來標明會丟出的例外,並附上簡單說明。下面範例的說明中沒有提到當 m = null 時的情況,這是因為在 m 生成 BigInteger 時就會作類似的檢查。對於 non-public 方法,可以使用斷言 (assertion) 來檢查,程式碼用 assert 來撰寫。
/**
* @param m the modulus.
* @return this mod m
* @throws ArithmeticException m <= 0
*/
public BigInteger mod(BigInteger m) {
if (m.signum <= 0)
throw new ArithmeticException("BigInteger: modulus not positive");
...
}
對於有些參數是傳入後被保存起來,後續才會使用,這類的參數更應該作檢查。Constructor 正是上述的例子,根本不需要生成一個違反約束條件的實體。那何時應該放棄這項原則,當有效性檢查的成本非常高時或是檢查會隱含在後續的方法中,舉例來說,排序時是否需要檢查傳入的參數都是 Comparable? 答案是不需要,因為在執行 compare 方法時,如果無法比較,便會丟出 ClassCastException,這時可以使用例外轉換 (exception translation) 的概念,將例外包裝成符合該方法定義所丟出的例外。轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2021/03/effective-java-49-parameter.html
沒有留言:
張貼留言