We use constructors to initialize non-static fields of a class. The constructors are called at the time of object creation and complete the initializations defined in them before the object becomes ready to use. We may use the same constructors to initialize static fields of the class. Initializing the static fields in a constructor means that we have to wait until the time of object creation. In certain situations, we will want to initialize the static fields before a class is instantiated. Consider the situation where we have defined a class called GoogleConnector that provides a connection to the Google website. When the user of this class instantiates it, he would naturally expect that the connection is already made and readily available to his code. If connection-making code is written in the class constructor, at times the connection may fail and the created object would not have access to the Google site. Ideally, if we make this connection while loading the class, it will be available to all its created objects. Java allows us to perform these initializations of static fields in what is called a static initializer or simply a static constructor.
A static initializer block resembles a method with no name, no arguments, and no return type. The name is not required because there is no need to refer to it from outside the class definition. Therefore, it is like an anonymous method. Whereas a typical class constructor may contain arguments, a static block cannot have any arguments. Because the static block is executed automatically during the class load time, the arguments to it will not make any sense, and therefore no arguments are allowed. Finally, like a constructor, the static block has no return type.
In our ExtendedBallGame from the previous post, we defined a static field called radius. We initialized it to zero at the time of its declaration. Alternatively, we could have defined a static initializer, as follows, to initialize the static field:
radius = 5;
Now, every ball object will have a default radius of 5 that can be set to
another value by calling the setRadius method elsewhere in the object
Advantages of a Static Initializer
Although the example in this section illustrates a simple case where a static block is used for initializing a single static field, which could be done by other ways, too, its real purpose lies in the initialization and allocation of resources that are required throughout the life of the class. Here are a few examples:
· A Modem class may perform initializations of its registers in a static block.
· A device driver may register the required natives in a static block.
· In some situations, initialization of a static field may require some prior computations. For example, a digital key signature algorithm may require a random-seed value based on the current time. This would require reading the current time and performing some computations before the seed is generated. Such code may be executed in a static block so that when the class is loaded, the seed for the key generator is readily available.
· Sometimes you may want to audit whether anybody has loaded a class that has access to sensitive information, as is typical in banking and military applications. A static block can be used for logging such activities.
· For a typical database application, you may generate prepared SQL statements in a static block.
· In singletons, you may declare private static members that are initialized in a static block only once. (The singleton is a design pattern that implements the mathematical concept of a singleton by restricting the instantiation of a class to one object.)