What is an initialization block?

后端 未结 10 1861
青春惊慌失措
青春惊慌失措 2020-11-22 03:42

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?

相关标签:
10条回答
  • 2020-11-22 03:48

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

    0 讨论(0)
  • 2020-11-22 03:49

    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 itialization 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.

    0 讨论(0)
  • 2020-11-22 03:49

    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.

    0 讨论(0)
  • 2020-11-22 03:51
    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
    
    0 讨论(0)
  • 2020-11-22 03:53

    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.

    0 讨论(0)
  • 2020-11-22 03:57

    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
    
    0 讨论(0)
提交回复
热议问题