Initialization

Before you can program, you need to know what you can count on. Being able to make accurate assumptions helps you focus on learning what you need to know. One issue about which it is helpful to be able to make assumptions is the state of variables. Initialization is the process of putting variables into a known state before they are used.

There are several issues in initializing variables. One is the desire to make initialization as declarative as possible. If initialization and declaration go together, there is one place to go for answers to questions about the variable. Another issue is performance. Variables that are expensive to initialize may need to be initialized some time after they come into existence. For example, in Eclipse, classes are loaded as late as possible to keep start-up time low.

Eager Initialization

One style of initialization is to initialize a variable as soon as it comes into exist-ence—when it is declared or when the object in which it lives is created (declaration or constructor). One advantage of eager initialization is that you can be assured that the variables are initialized before they are used.

Initialize variables in the declaration if possible. This puts the declared and actual types close together for readers.

class Library {
List<Person> members= new ArrayList<Person>();

}

Initialize fields in the constructor if they can’t be initialized in the declaration:

class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}

There is a certain symmetry to initializing all the fields of an object in the same place, either the declarations or the constructor. However, mixing the two styles doesn’t seem to cause any confusion as long as the objects are kept to a reasonable size.

Lazy Initialization

Eager initialization works well when you don’t mind paying the cost of computing a variable’s value when the variable comes into existence. When the computation is expensive and you would like to defer the cost (perhaps because the variable may never be used), create a getter method and initialize the field when the getter is first called:

Library.Collection<Person> getMembers() {
if (members == null) members = new ArrayList<Person>();
return members;
}

Lazy initialization used to be a more common technique. Limitation in raw computing power was more often an issue. Lazy initialization is important when computational power is a limited resource. A resource-constrained environment like Eclipse, where start-up must be fast, uses lazy initialization to avoid loading plug-ins until they are about to be used.

A lazily initialized field is harder to read than one initialized eagerly. The reader has to look at least two places before understanding the implementation type of the field. When coding, you are storing information for future readers. Fortunately, there are only a few commonly asked questions, so a few techniques suffice to answer most of them. Lazy initialization says, “Performance is important here.”

Implementation Patterns

contents