The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Initializing Instance and Class Members

You can provide an initial value for a class or an instance member variable in its declaration:
public class BedAndBreakfast {
    //initialize to 10
    public static final int MAX_CAPACITY = 10;
    //initialize to false
    private boolean full = false;
}
This works well for member variables of primitive data types. Sometimes, it even works when creating arrays and objects. But this form of initialization has limitations. If these limitations prevent you from initializing a member variable in its declaration, you have to put the initialization code elsewhere. To initialize a class member variable, put the initialization code in a static initialization block, as the following section shows. To initialize an instance member variable, put the initialization code in a constructor.

Using Static Initialization Blocks

Here's an example of a static initialization block:
import java.util.*;

class Errors {
    static ResourceBundle errorStrings;
    static {
        try {
            errorStrings = 
               ResourceBundle.getBundle("ErrorStrings");
        } catch (MissingResourceException e) {
            //error recovery code here
        }
    }
}
A static initialization block begins with the static keyword and is a normal block of code enclosed in braces: { and }. The errorStrings resource bundle must be initialized in a static initialization block because the getBundle method can throw an exception if the bundle cannot be found. The code should perform error recovery. Also, errorStrings is a class member, so it should not be initialized in a constructor.

A class can have any number of static initialization blocks that appear anywhere in the class body. The runtime system guarantees that static initialization blocks and static initializers are called in the order (left to right, top to bottom) that they appear in the source code.

There is an alternative to static blocks — write a private static method:

import java.util.*;

class Errors {
    static ResourceBundle errorStrings = initErrorStrings();
    private static ResourceBundle initErrorStrings() {
        try {
            return ResourceBundle.getBundle("ErrorStrings");
        } catch (MissingResourceException e) {
            //error recovery code here
        }
    }
}
The advantage of private static methods is that they can be reused later if you need to reinitialize the class. In this example, that could be useful if a new translation is installed.

Initializing Instance Members

If you want to initialize an instance variable and cannot do it in the variable declaration for the reasons cited previously, put the initialization in the constructor(s) for the class. If the errorStrings bundle in the previous example were an instance variable rather than a class variable, you'd move the code that initializes errorStrings to a constructor for the class, as follows:
import java.util.*;
class Errors {
    ResourceBundle errorStrings;
    Errors() {
        try {
            errorStrings =
              ResourceBundle.getBundle("ErrorStrings");
        } catch (MissingResourceException e) {
            //error recovery code here
        }
    }
}
There are two alternatives to initializing instance members: final methods and initializer blocks. Here is an example of using a final method for initializing:
import java.util.*;

class Errors {
    ResourceBundle errorStrings = initErrorStrings();
    protected final ResourceBundle initErrorStrings() {
        try {
            return ResourceBundle.getBundle("ErrorStrings");
        } catch (MissingResourceException e) {
            //error recovery code 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 (outside of the tutorial).

A third alternative is initializer blocks:

class Errors {
    try {
        errorStrings = ResourceBundle.getBundle("ErrorStrings");
    } catch (MissingResourceException e) {
        //error recovery code here
    }
}
The Java compiler copies initializer blocks into every constructor. So this approach is useful for sharing code between multiple constructors.

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.