You will often see that the code does not initialize the class simply by calling the constructor, it also initializes the class with some immediate action intended to set the fields. Unfortunately, this next action is the wrong high zone, which leads to a continuous initialization (run-on initialization) type of error.
Continuous initialization
For a variety of reasons (mostly bad), you will often see such a class definition where the class constructor does not have enough arguments to properly initialize all the fields of the class. Such a constructor requires the client class to initialize the instance with several steps (setting the value of the domain not initialized), rather than using a constructor call. Initializing an instance in such a way is an error-prone process, which I call continuous initialization. The various types of errors produced by this process have similar symptoms and treatments, so we can classify them all into a pattern called the continuous initializer error pattern.
For example, consider the following code:
Listing 1. A simple, continuous initialization
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);
}
}