What is an initialization block?
Asked Answered
I

10

131

We can put code in a constructor or a method or an initialization block. What is the use of initialization block? Is it necessary that every java program must have it?

Indecent answered 21/10, 2010 at 12:28 Comment(3)
Do you mean an init() function called by or after the constructoe? Or a sttatic block declared outside any method?Mcgurn
I can't see clearly what is your question, maybe the title is a little misleadingLogger
possible duplicate of Use of Initializers vs Constructors in JavaKinship
B
224

First of all, there are two types of initialization blocks:

  • instance initialization blocks, and
  • static initialization blocks.

This code should illustrate the use of them and in which order they are executed:

public class Test {
    
    static int staticVariable;
    int nonStaticVariable;        

    // Static initialization block:
    // Runs once (when the class is initialized)
    static {
        System.out.println("Static initalization.");
        staticVariable = 5;
    }
    
    // Instance initialization block:
    // Runs each time you instantiate an object
    {
        System.out.println("Instance initialization.");
        nonStaticVariable = 7;
    }
    
    public Test() {
        System.out.println("Constructor.");
    }
    
    public static void main(String[] args) {
        new Test();
        new Test();
    }
}

Prints:

Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.

Instance initialization blocks are useful if you want to have some code run regardless of which constructor is used or if you want to do some instance initialization for anonymous classes.

Bithia answered 21/10, 2010 at 12:46 Comment(3)
At the moment it looks like they are executed in order of appearance in the code. The example could be improved in the way the order in code is different to the actual execution order. Also: there can be several initialization blocks and then they are executed in order of appearance (but still before the constructor).Dimitris
@Pacerier So you can have common code when having multiple constructors without having to use an init() method (which someone updating the class may forget to call it)Worms
@Thomas wellerif its executes before constructor how come it allows this keyword inisde instance initialize block . this is curernt class object and it will constructed fully after the constructor call finishes right?Kettledrum
R
115

would like to add to @aioobe's answer

Order of execution:

  1. static initialization blocks of super classes

  2. static initialization blocks of the class

  3. instance initialization blocks of super classes

  4. constructors of super classes

  5. instance initialization blocks of the class

  6. constructor of the class.

A couple of additional points to keep in mind (point 1 is reiteration of @aioobe's answer):

  1. The code in static initialization block will be executed at class load time (and yes, that means only once per class load), before any instances of the class are constructed and before any static methods are called.

  2. The instance initialization block is actually copied by the Java compiler into every constructor the class has. So every time the code in instance initialization block is executed exactly before the code in constructor.

Rabideau answered 14/3, 2013 at 15:36 Comment(6)
So if I create 10 instances of SomeClass, steps 1 and 2 only get performed once, until something causes the class to get unloaded (only thing I can think of is restarting the program, but if there are other things that can cause that, I'd like to know).Lurlenelurline
@GlenPierce here you go: docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.7Rabideau
Will a child class inherit the instance initialization block?Straggle
No, inheritance does not apply to initialization blocksRabideau
The instance initialization block is actually copied by the Java compiler into every constructor the class has - this is not always true. It will not be copied if the constructor explicitily invokes another constructor.Procumbent
@Procumbent is it because if a constructor is explicitly invoked within another constructor, it has to be the first statement ?Yoghurt
B
12

nice answer by aioobe adding few more points

public class StaticTest extends parent {
    static {
        System.out.println("inside satic block");
    }

    StaticTest() {
        System.out.println("inside constructor of child");
    }

    {
        System.out.println("inside initialization block");
    }

    public static void main(String[] args) {
        new StaticTest();
        new StaticTest();
        System.out.println("inside main");
    }
}

class parent {
    static {
        System.out.println("inside parent Static block");
    }
    {
        System.out.println("inside parent initialisation block");
    }

    parent() {
        System.out.println("inside parent constructor");
    }
}

this gives

inside parent Static block
inside satic block
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside main

its like stating the obvious but seems a little more clear.

Breadboard answered 3/7, 2014 at 6:36 Comment(0)
B
4

The sample code, which is approved as an answer here is correct, but I disagree with it. It does not shows what is happening and I'm going to show you a good example to understand how actually the JVM works:

package test;

    class A {
        A() {
            print();
        }

        void print() {
            System.out.println("A");
        }
    }

    class B extends A {
        static int staticVariable2 = 123456;
        static int staticVariable;

        static
        {
            System.out.println(staticVariable2);
            System.out.println("Static Initialization block");
            staticVariable = Math.round(3.5f);
        }

        int instanceVariable;

        {
            System.out.println("Initialization block");
            instanceVariable = Math.round(3.5f);
            staticVariable = Math.round(3.5f);
        }

        B() {
            System.out.println("Constructor");
        }

        public static void main(String[] args) {
            A a = new B();
            a.print();
            System.out.println("main");
        }

        void print() {
            System.out.println(instanceVariable);
        }

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

Before to start commenting on the source code, I'll give you a short explanation of static variables of a class:

First thing is that they are called class variables, they belong to the class not to particular instance of the class. All instances of the class share this static(class) variable. Each and every variable has a default value, depending on primitive or reference type. Another thing is when you reassign the static variable in some of the members of the class (initialization blocks, constructors, methods, properties) and doing so you are changing the value of the static variable not for particular instance, you are changing it for all instances. To conclude static part I will say that the static variables of a class are created not when you instantiate for first time the class, they are created when you define your class, they exist in JVM without the need of any instances. Therefor the correct access of static members from external class (class in which they are not defined) is by using the class name following by dot and then the static member, which you want to access (template: <CLASS_NAME>.<STATIC_VARIABLE_NAME>).

Now let's look at the code above:

The entry point is the main method - there are just three lines of code. I want to refer to the example which is currently approved. According to it the first thing which must be printed after printing "Static Initialization block" is "Initialization block" and here is my disagreement, the non-static initialization block is not called before the constructor, it is called before any initializations of the constructors of the class in which the initialization block is defined. The constructor of the class is the first thing involved when you create an object (instance of the class) and then when you enter the constructor the first part called is either implicit (default) super constructor or explicit super constructor or explicit call to another overloaded constructor (but at some point if there is a chain of overloaded constructors, the last one calls a super constructor, implicitly or explicitly).

There is polymorphic creation of an object, but before to enter the class B and its main method, the JVM initializes all class(static) variables, then goes through the static initialization blocks if any exist and then enters the class B and starts with the execution of the main method. It goes to the constructor of class B then immediately (implicitly) calls constructor of class A, using polymorphism the method(overridden method) called in the body of the constructor of class A is the one which is defined in class B and in this case the variable named instanceVariable is used before reinitialization. After closing the constructor of class B the thread is returned to constructor of class B but it goes first to the non-static initialization block before printing "Constructor". For better understanding debug it with some IDE, I prefer Eclipse.

Ballard answered 14/3, 2014 at 13:48 Comment(4)
TL;DR OP simply asked for an explanation of the initialization block, not a long-winded explanation on the fundamentals of static variables, constructors, or your IDE preferences.Fervent
Sometimes, these longwinded explanations can get unexpectedly popular. Either if those asking the original question really need a longwinded explanation to get their foundations straight. Or if people read the answer by itself, as if it was a blog on a given topic. In this instance, it is neither, I'd say.Grano
@nenito, I think that your comment on the accepted answer is misleading. I encourage you to rephrase it to something more like "I have a more nuanced explanation that may be of interest." The accepted answer does seem to be exactly correct, simply not as detailed as yours.Lurlenelurline
@Glen Pierce: The accepted answer was modified after my comment. My sentence gives not only the answer but also some additional info which I think is useful for junior and intermediate level Java developers.Ballard
H
2

Initializer block contains the code that is always executed whenever an instance is created. It is used to declare/initialise the common part of various constructors of a class.

The order of initialization constructors and initializer block doesn’t matter, initializer block is always executed before constructor.

What if we want to execute some code once for all objects of a class?

We use Static Block in Java.

Hazelwood answered 10/10, 2016 at 9:45 Comment(0)
S
1

In addition to what was said in previous answers, blocks can be synchronized .. never felt I need to use it, however,it's there

Stinky answered 9/8, 2020 at 23:55 Comment(0)
P
0

Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces. It is not at all necessary to include them in your classes.

They are typically used to initialize reference variables. This page gives a good explanation

Postboy answered 21/10, 2010 at 12:39 Comment(1)
According to @Biman, the constructors from superclasses are run before the init block.Philippians
S
0

The question is not entirely clear, but here's a brief description of ways you can initialise data in an object. Let's suppose you have a class A that holds a list of objects.

1) Put initial values in the field declaration:

class A {
    private List<Object> data = new ArrayList<Object>();
}

2) Assign initial values in the constructor:

class A {
    private List<Object> data;
    public A() {
        data = new ArrayList<Object>();
    }
}

These both assume that you do not want to pass "data" as a constructor argument.

Things get a little tricky if you mix overloaded constructors with internal data like above. Consider:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        data = new ArrayList<Object>();
        name = "Default name";
        userFriendlyName = "Default user friendly name";
    }

    public B(String name) {
        data = new ArrayList<Object>();
        this.name = name;
        userFriendlyName = name;
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

Notice that there is a lot of repeated code. You can fix this by making constructors call each other, or you can have a private initialisation method that each constructor calls:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        this("Default name", "Default user friendly name");
    }

    public B(String name) {
        this(name, name);
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

or

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        init("Default name", "Default user friendly name");
    }

    public B(String name) {
        init(name, name);
    }

    public B(String name, String userFriendlyName) {
        init(name, userFriendlyName);
    }

    private void init(String _name, String _userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

The two are (more or less) equivalent.

I hope that gives you some hints on how to initialise data in your objects. I won't talk about static initialisation blocks as that's probably a bit advanced at the moment.

EDIT: I've interpreted your question as "how do I initialise my instance variables", not "how do initialiser blocks work" as initialiser blocks are a relatively advanced concept, and from the tone of the question it seems you're asking about the simpler concept. I could be wrong.

Sublet answered 21/10, 2010 at 12:45 Comment(1)
Even if you interpreted the question as "How do I initialise my instance variables?", your answer does not mention that it can be done with initializers.Dimitris
C
0
public class StaticInitializationBlock {

    static int staticVariable;
    int instanceVariable;

    // Static Initialization Block
    static { 
        System.out.println("Static block");
        staticVariable = 5;

    }

    // Instance Initialization Block
    { 

        instanceVariable = 7;
        System.out.println("Instance Block");
        System.out.println(staticVariable);
        System.out.println(instanceVariable);

        staticVariable = 10;
    }


    public StaticInitializationBlock() { 

        System.out.println("Constructor");
    }

    public static void main(String[] args) {
        new StaticInitializationBlock();
        new StaticInitializationBlock();
    }

}

Output:

Static block
Instance Block
5
7
Constructor
Instance Block
10
7
Constructor
Chive answered 5/2, 2015 at 23:30 Comment(0)
S
0

Just to add to the excellent answers from @aioobe and @Biman Tripathy.

A static initializer is the equivalent of a constructor in the static context. which is needed to setup the static environment. A instance initializer is best for anonymous inner classes.

  • It is also possible to have multiple initializer blocks in class
  • When we have multiple initializer blocks they are executed (actually copied to constructors by JVM) in the order they appear
  • Order of initializer blocks matters, but order of initializer blocks mixed with Constructors doesn't
  • Abstract classes can also have both static and instance initializer blocks.

Code Demo -

abstract class Aircraft {

    protected Integer seatCapacity;

    {   // Initial block 1, Before Constructor
        System.out.println("Executing: Initial Block 1");
    }

    Aircraft() {
        System.out.println("Executing: Aircraft constructor");
    }

    {   // Initial block 2, After Constructor
        System.out.println("Executing: Initial Block 2");
    }

}

class SupersonicAircraft extends Aircraft {

    {   // Initial block 3, Internalizing a instance variable
        seatCapacity = 300;
        System.out.println("Executing: Initial Block 3");
    }

    {   // Initial block 4
        System.out.println("Executing: Initial Block 4");
    }

    SupersonicAircraft() {
        System.out.println("Executing: SupersonicAircraft constructor");
    }
}

An instance creation of SupersonicAircraft will produce logs in below order

Executing: Initial Block 1
Executing: Initial Block 2
Executing: Aircraft constructor
Executing: Initial Block 3
Executing: Initial Block 4
Executing: SupersonicAircraft constructor
Seat Capacity - 300
Stately answered 4/1, 2020 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.