您經常會看到代碼不是僅僅通過調用建構函式對類進行初始化,它還通過一些緊接著的意在設定各個域的動作對類進行初始化。不幸的是,這樣緊接著的動作是錯誤的高發地帶,會帶來連續初始化(run-on initialization)類型的錯誤。
連續初始化
由於各種原因(多數是糟糕的),您經常會看到這樣的類定義,其中的類建構函式並不帶有足夠的參數來適當地初始化類的所有域。這樣的建構函式要求客戶機類用幾個步驟來對執行個體進行初始化(設定未被初始化的域的值),而不是用一個建構函式調用就行了。以這樣的方式初始化執行個體是一個易於出錯的過程,我把它稱為 連續初始化。這個過程產生的各種錯誤類型有相似的癥狀和治療方法,所以我們可以將它們統統歸入一種稱為 連續初始化器錯誤模式的模式。
例如,考慮以下代碼:
清單 1. 一個簡單的連續初始化
class RestrictedInt {
public Integer value;
public boolean canTakeZero;
public RestrictedInt(boolean _canTakeZero) {
canTakeZero = _canTakeZero;
}
public void setValue(int _value) throws CantTakeZeroException {
if (_value == 0) {
if (canTakeZero) {
value = new Integer(_value);
}
else {
throw new CantTakeZeroException(this);
}
}
else {
value = new Integer(_value);
}
}
}
class CantTakeZeroException extends Exception {
public RestrictedInt ri;
public CantTakeZeroException(RestrictedInt _ri) {
super("RestrictedInt can't take zero");
ri = _ri;
}
}
class Client {
public static void initialize() throws CantTakeZeroException {
RestrictedInt ri = new RestrictedInt(false);
ri.setValue(0);
}
}