Static Initialization Blocks

Static Initialization Blocks

The non-static block:

{
// Do Something...
}

Gets called every time an instance of the class is constructed. The static block only gets called once, when the class itself is initialized, no matter how many objects of that type you create.

Example:

public class Test {

static{
System.out.println("Static");
}

{
System.out.println("Non-static block");
}

public static void main(String[] args) {
Test t = new Test();
Test t2 = new Test();
}
}

This prints:

Static
Non-static block
Non-static block

Static and Non-Static initialization blocks in Java

Non-static initialization blocks will be called on instance creation.

You never create a new instance, so the block is not executed.

Difference between the static initializer block and regular static initialization

For your example, there is no difference. But as you can see,

public static String myString = "Hello World!";

can only accept an expression to initialize the variable. However, in a static initializer (JLS 8.7), any number of statements may be executed. E.g. it's possible to do this:

static
{
myString = "Hello";
myString += " ";
myString += "World";
}

For your example, there's obviously no need to do that, but it's possible for the initialization of a variable to take more than an expression, perhaps many statements, so Java made static initializers.

Why would I use static initialization block in java?

Firstly, you might never have any instances of your class. Or you might want to have the static members iniailized before you have any instances of the class.

Secondly, initializing static members from constructors is more work:

  • you'll need to make sure that every constructor does this;
  • you need to maintain a flag to keep track of whether static members have been initialized;
  • you have to think about synchronization to prevent race conditions;
  • you may have to consider performance implications of the synchronization, especially if you have many threads creating many instances of your class.

Lastly, it's usually the wrong thing to do conceptually (I say "usually" because there are legitimate uses for lazy initialization).

Java: When is a static initialization block useful?

A static initialization blocks allows more complex initialization, for example using conditionals:

static double a;
static {
if (SomeCondition) {
a = 0;
} else {
a = 1;
}
}

Or when more than just construction is required: when using a builder to create your instance, exception handling or work other than creating static fields is necessary.

A static initialization block also runs after the inline static initializers, so the following is valid:

static double a;
static double b = 1;

static {
a = b * 4; // Evaluates to 4
}

Static block vs. initializer block in Java?

They're for two very different purposes:

  • The static initializer block will be called on loading of the class, and will have no access to instance variables or methods. As per @Prahalad Deshpande's comment, it is often used to create static variables.
  • The non-static initializer block on the other hand is created on object construction only, will have access to instance variables and methods, and (as per the important correction suggested by @EJP) will be called at the beginning of the constructor, after the super constructor has been called (either explicitly or implicitly) and before any other subsequent constructor code is called. I've seen it used when a class has multiple constructors and needs the same initialization code called for all constructors. Just as with constructors, you should avoid calling non-final methods in this block.

Note that this question has been answered many times in stackoverflow and you would do well to search and review the similar questions and their answers. For example: static-initialization-blocks

Why are static blocks/static variables in super class initialized before main?

static initializer blocks are called when the class loader loads a class. In a nutshell, the order of execution here is as follows:

  1. Attempt to load test, see it depends on sub
  2. Attempt to load sub, see it depends on sup
  3. Attempt to load sup
  4. sup is loaded, and its static block prints "In Sup"
  5. sub's loading is resumed, and its static block prints "In Sub"
  6. test's loading is resumed, and a is initialized to 10.
  7. test's static block is executed and prints " In test10"
  8. test's main function is executed, and does nothing, since it's empty.

static initialization block vs constructor java

Strictly speaking, static initializers are executed, when the class is initialized.

Class loading is a separate step, that happens slightly earlier. Usually a class is loaded and then immediately initialized, so the timing doesn't really matter most of the time. But it is possible to load a class without initializing it (for example by using the three-argument Class.forName() variant).

No matter which way you approach it: a class will always be fully initialized at the time you create an instance of it, so the static block will already have been run at that time.



Related Topics



Leave a reply



Submit