Tutorial Java SCJP – #18 Initialization blocks

1 comment - This post in romanian

In order to process something you need values. And values are usually stored in static variables, local variables (defined in methods) or instance variables (nonstatic variables defined in classes). In order to initialize a variable you can do it at definition or later in a method (constructor or not). Despite these two common solutions, there is another way using initialization blocks.

Initialization blocks are blocks of codes defined between { and }. At this point they are like methods blocks, but the main difference is that initialization blocks don’t have  a name. They are like methods but without the method header (return type, name, parameter list).

Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents.

Like most everything in Java, initializations blocks are also defined in a class and not globally.

An example of initialization block is:

public class Main {
    //static initialization block
    static
    {
        System.out.println("This is a static initialization block !");
    }
    //initialization block
    {
        System.out.println("This is an initialization block !");
    }
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("This is the main method !");
    }
}

If you run the previous example, the output is:

This is a static initialization block !
This is the main method !

As you can see, from the previous example, there are two types of initialization blocks with different behaviors:

  • static initialization blocks – blocks of code which are executed ONLY ONCE when the class is loaded by the Java Virtual Machine; this is why the static initialization block message is printed before the main() method one; these types of initialization blocks are useful for initializing static attributes or to execute one time only a set of statements;
  • initialization blocks (instance initialization blocks) – blocks of code which are executed every time a class instance is created (when the constructor is called); these instance initialization blocks are used to initialize static attributes or to implement generic processing that is performed each time an object is built regardless of the called constructor (you can have multiple constructors with different parameters lists)

Based on this descriptions, the next example

class Test{
    //static initialization block
    static
    {
        System.out.println("This is a static Test initialization block !");
    }
    //initialization block
    {
        System.out.println("This is a Test initialization block !");
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println("This is the main method !");
        Test t1 = new Test();
        Test t2 = new Test();
        System.out.println("This is the end of the main method !");
    }
}

generates the output:

This is the main method !
This is a static Test initialization block !
This is a Test initialization block !
This is a Test initialization block !
This is the end of the main method !

As you can see in the previous example, it is important to identify correctly in which class are defined the initialization blocks because static initialization blocks are executed when the class is loaded by the JVM and initialization blocks are executed every time an instance is created.

You can see that at the console output the first message is the one from the the main() method. The explication is that the Test class is loaded by the JVM right before the first instance is created (by the Test t1 = new Test() statement) but after the Main class has already been loaded.

Contrary to that, in the first example the static initialization block was defined in the Main class and it was executed when the Main class has been loaded by the JVM, before the execution of the main() method.

In the previous example, if you comment the lines

        //Test t1 = new Test();
        //Test t2 = new Test();

then the output is:

This is the main method !
This is the end of the main method !

You can define as many initialization blocks (static or not) you want but pay attention to their order of definition, because that is their order of execution:

class Test
{
    //static initialization block
    static
    {
        System.out.println("This is static Test initialization block - 1 !");
    }
    //initialization block
    {
        System.out.println("This is Test initialization block 1!");
    }
    //initialization block
    {
        System.out.println("This is Test initialization block 2!");
    }
    static
    {
        System.out.println("This is static Test initialization block - 2 !");
    }
}
 
public class Main {
    //static initialization block
    static
    {
        System.out.println("This is Main static initialization block !");
    }
    //initialization block
    {
        System.out.println("This is an initialization block !");
    }
    public static void main(String[] args) {
        System.out.println("This is the main method !");
        Test t1 = new Test();
        Test t2 = new Test();
        System.out.println("This is the end of the main method !");
    }
}

The output is:

1
2
3
4
5
6
7
8
9
This is Main static initialization block !
This is the main method !
This is static Test initialization block - 1 !
This is static Test initialization block - 2 !
This is Test initialization block 1!
This is Test initialization block 2!
This is Test initialization block 1!
This is Test initialization block 2!
This is the end of the main method !

because:

  1. the Main class is loaded in order to execute main(); the Main static initialization bloc is executed;
  2. the main() method is executed
  3. the first Test static initialization block is executed because the Test class is loaded in order to create t1 instance
  4. the second Test static initialization block is executed because the Test class is loaded in order to create t1 instance
  5. the first Test instance, t1, is created and it is executed the first instance initialization block
  6. the first Test instance, t1, is created and it is executed the second instance initialization block

Initialization blocks and class variables

Initialization blocks are associated with a class and its instances. So let’s see what types of class variables can be used in initialization blocks:

  • static initialization blocks can access ONLY class static variables; you can’t use instance variables in static initialization blocks (if you try you get a non-static variable value cannot be referenced from a static context exception);
  • instance initialization blocks can access class static variables and instance variables (the instance variables are the attributes of the constructed instance) because they are executed right before an instance is created;
class Test
{
    public int value;
    public static int staticValue;
    //static initialization block
    static
    {
        System.out.println("This is static Test initialization block - 1 !");
        staticValue = 23;
        //value = 50;     //compiler exception
    }
    //initialization block
    {
        System.out.println("This is Test initialization block 1!");
        value = 50;
    }
}
 
public class Main {
    public static void main(String[] args) {
        Test t1 = new Test();
        System.out.println("staticValue ="+Test.staticValue);
        System.out.println("t1.value = "+t1.value);
    }
}

and the output is

This is static Test initialization block - 1 !
This is Test initialization block 1!
staticValue =23
t1.value = 50

Initialization blocks and hierarchies of classes

Static initialization blocks are executed in the

  1. base class
  2. subclass
    1. sequence because each static initialization blocks is executed before its class is loaded.

      Initialization blocks are executed after the constructor call to super() (the base class constructor);

      The next example

      class Base{
          static
          {
              System.out.println("Base class static initialization block !");
          }
          {
              System.out.println("Base class initialization block !");
          }
          public Base() { System.out.println("Base class constructor !");}
      }
      class Child extends Base{
          public Child()
          {
              System.out.println("Child class constructor !");
          }
          static
          {
              System.out.println("Child class static initialization block !");
          }
          {
              System.out.println("Child class initialization block !");
          }
      }
      public class Main {
          public static void main(String[] args) {
              Child c = new Child();
          }
      }

      generates the next ouput:

      Base class static initialization block !
      Child class static initialization block !
      Base class initialization block !
      Base class constructor !
      Child class initialization block !
      Child class constructor !

      For the SCJP exam remember:

      • static initialization blocks are executed ONLY ONCE when the class is loaded by the JVM;
      • verify the class in which is defined main() and the class in which are defined initialization blocks in order to determine the output;
      • initialization blocks (or instance initialization blocks) are executed every time a class instance is created;
      • instance initialization blocks are executed in the order they are defined;
      • instance initialization blocks are executed after the constructor call to super() ;
      • instance initialization blocks have access to instance variables and class static variables;
      • static initialization blocks have access ONLY to the class static variables.

      Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents.


  1. No comments yet.
(will not be published)