As you have seen, you can often provide an initial value for a field in its declaration:
public class BedAndBreakfast {
public static int capacity = 10; //initialize to 10
private boolean full = false; //initialize to false
}
This works well when the initialization value is available and the initialization can be put on one line.
However, this form of initialization has limitations because of its simplicity.
If initialization requires some logic
(for example, error handling or a
for
loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error handling or other logic
can be used. To provide the same capability for class variables, the Java programming language includes
static initialization blocks.
Note: It is not necessary to declare fields at the beginning of the class definition, although this is the
most common practice. It is only necessary that they be declared and initialized before they are used.
Static Initialization Blocks
A
static initialization block is a normal block of code enclosed in braces,
{ }
, and preceded by the
static
keyword. Here is an example:
static {
// whatever code is needed for initialization goes here
}
A class can have any number of static initialization blocks, and they can
appear anywhere in the class body. The runtime system guarantees
that static initialization blocks are called in the order that they
appear in the source code.
There is an alternative to static blocks — you can write a private
static method:
class Whatever {
public static varType myVar = initializeClassVariable();
private static varType initializeClassVariable() {
//initialization code goes here
}
}
The advantage of private static methods is that they can be reused later
if you need to reinitialize the class variable.
Initializing Instance Members
Normally, you would put code to initialize an instance variable in a constructor.
There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final
methods.
Initializer blocks for instance variables look just like static initializer blocks, but without
the static
keyword:
{
// whatever code is needed for initialization goes here
}
The Java compiler copies initializer blocks into every constructor.
Therefore, this approach can be used to share a block of code between multiple constructors.
A final method cannot be overridden in a subclass. This is discussed in
the lesson on
interfaces and inheritance.
Here is an example of using a final
method for initializing an instance variable:
class Whatever {
private varType myVar = initializeInstanceVariable();
protected final varType initializeInstanceVariable() {
//initialization code goes here
}
}
This is especially useful if subclasses might want to reuse the
initialization method. The method is final because calling non-final
methods during instance initialization can cause problems.
Joshua Bloch describes this in more detail in
Effective Java.