Static Initializer Block

The static initializer block is a very interesting item in Java that unknown by most of the Java novice community; it is glossed over in Java books but none of the books really go into any sort of dept. Understanding “what it is” and “how it works” are two very important concepts about static initializers that every Java developer should know.

What Is It?

  • A block of code ‘{ }’ that runs only one time, and it is run the first time the Constructor or the main() method for that class is called (Sun calls this ‘when the class is initialized‘)

How Does It Work?

  • Just declare a static { } block inside your Java class and throw some code in it
  • No return statement
  • No access to this or super
  • Can throw Unchecked Exceptions only

What Can It Be Used For?

  • Loading drivers and other items into the namespace. (For example ‘Class.forName(“com.mysql.jdbc.Driver”)’)
  • Initialize your complex static members once (possibly for singletons/etc)
  • Logging
  • Creating/parsing prepared SQL statements

Time to Play

I have created 2 simple classes to play around with the static initializer class: Loader and Test:

class Loader {
    static final String theName = "The Loader";
    static {
        System.out.println("Loader.static");
    }
    Loader() {
        System.out.println("Loader.Loader()");
    }
}

class Test {
    static {
        System.out.println( "Test.static");
    }
    Test() {
        System.out.println( "Test.Test()");
    }
    public static void main( String [] args ) {
        System.out.println( "Test.main");
        Test t = new Test();
        System.exit(0);
    }
}

If we compile and run Test the output we see is:

Test.static
Test.main
Test.Test()

So we see that static block code is called before the main method is executed. Now, let’s define a Loader variable in the constructor and print out ‘Loader.name’.

class Test {
    static {
        System.out.println( "Test.static");
    }
    Test() {
        System.out.println( "Test.Test()");
        // Define a loader and print out the static name
        Loader l;
        System.out.println( Loader.theName );
    }
    public static void main( String [] args ) {
        System.out.println( "Test.main");
        Test t = new Test();
        System.exit(0);
    }
}

When we compile Test and run it, we now see this:

Test.static
Test.main
Test.Test()
The Loader

So, we can see that neither defining a class nor accessing static class members constitutes “initializing” a class (which would call the static block).

Hmm, ok well lets initialize a few instances of a Loader instead:

class Test {
    static {
        System.out.println( "Test.static");
    }
    Test() {
        System.out.println( "Test.Test()");
        // Make a few Loaders
        Loader l1 = new Loader();
        Loader l2 = new Loader();
        Loader l3 = new Loader();
    }
    public static void main( String [] args ) {
        System.out.println( "Test.main");
        Test t = new Test();
        System.exit(0);
    }
}

Now we compile and execute and we get the expected output:

Test.static
Test.main
Test.Test()
Loader.static
Loader.Loader()
Loader.Loader()
Loader.Loader()

The static block was called only once before the first time the constructor was called.

Well, What About Inheritance?

Let’s try it; we’ll have Test inherit from Loader.

class Test extends Loader {
    static {
        System.out.println( "Test.static");
    }
    Test() {
        System.out.println( "Test.Test()");
    }
    public static void main( String [] args ) {
        System.out.println( "Test.main");
        Test t = new Test();
        System.exit(0);
    }
}

Now if we compile and run Test we get the output:

Loader.static
Test.static
Test.main
Loader.Loader()
Test.Test()

Interesting, the static blocks get loaded first as usual, but the Loader class had it’s static block called first, which makes sense.

Static initializer blocks: interesting stuff.

11 thoughts on “Static Initializer Block

  1. Unfortunately SOMETHING IS WRONG HERE. Your proposition

    “So, we can see that neither defining a class nor accessing static class members constitutes “initializing” a class (which would call the static block).”

    is not true. If you ACCESS A STATIC FIELD before making an instance, INITIALIZER IS INVOKED yust after an initialization in declarations.

  2. @beavis42 Hmm. What version of Java are you using? I just compiled the 2 classes again (1.4 and 1.6 for bot Test and Loader) where Test prints Loader.theName (thereby invoking it); however, nothing else gets printed from Loader, so I would still venture to say that accessing static members does not invoke the static block. If it did, I would have expected to see “Loader.static” printed, but it’s not.

  3. I think the confusion here is that accessing a static member variable WILL NOT cause the static block to be invoked. However, calling a static member FUNCTION will cause it to be invoked – I just checked.

    engfer, thanks for helping me figure this out.

  4. Hey, Stingray, that’s exactly the information I wanted. I often want to initialize static collection members and that’s exactly how I have to do it. Thanks!

  5. Here’s my test code:

    public class Constants {
    private static final Set validValues;
    static {
    validValues = new HashSet();
    validValues.add(“value1″);
    validValues.add(“value2″);
    }

    public static Set getValidValues() {
    return validValues;
    }
    }

    public class Test {
    public static void main(String[] args) {
    System.out.println(“Valid values: ” Constants.getValidValues());
    }
    }

    And when I run Test:
    Valid values: [value1, value2]

  6. Hi, i tried following example, in this example i tried to access static variables of one class from another class which have main method, in this case also first class static block is executing. and i am using java 1.6 only

    Program:
    =======

    class StatTest {

    static int statVariable = 1;
    static {
    System.out.println(“Static block of StatTest method”);
    }

    public StatTest() {
    System.out.println(“Constructory of StatTest”);
    }

    }

    public class StatTest1 {

    static {
    System.out.println(“Static block of StatTest1″);
    StatTest.statVariable=5;
    }

    public static void main(String []args) {

    System.out.println(“StatTest2 main method”);

    }

    }

    and Output is:

    Static block of StatTest1
    Static block of StatTest method
    StatTest2 main method

  7. @all: Let me tell you what I found with 1.6.0_21:

    The static initializer (e.g. Loader.static, StatTest.static) is not invoked if the accessed variable (e.g. theName, statVariable) is a static _final of a primitive or of type String_. But, it is invoked with a variable of type Object, also if it is initialized with a String. WTF?!?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>