什么是初始化块?

Sum*_*hra 93 java constructor initialization initialization-block

我们可以将代码放在构造函数或方法或初始化块中.初始化块有什么用?每个java程序都必须拥有它吗?

aio*_*obe 169

首先,有两种类型的初始化块:

  • 实例初始化块,和
  • 静态初始化块.

此代码应说明它们的使用以及它们的执行顺序:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

打印:

Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.
Run Code Online (Sandbox Code Playgroud)

如果您想要运行某些代码而不管使用哪个构造函数,或者您希望为匿名类执行某些实例初始化,则实例itialization块非常有用.

  • 目前看起来它们是按照代码中的外观顺序执行的.可以通过代码中的顺序与实际执行顺序不同的方式来改进示例.另外:可以有几个初始化块,然后按照出现的顺序执行它们(但仍然在构造函数之前). (9认同)

Bim*_*thy 94

想加入@ aioobe的答案

执行顺序:

  1. 超类的静态初始化块

  2. 类的静态初始化块

  3. 实例初始化超类块

  4. 超类的构造者

  5. 实例初始化类的块

  6. 类的构造函数.

还要记住几点要点(第1点是对@ aioobe的回答的重申):

  1. 静态初始化块中的代码将在类加载时执行(是的,这意味着每个类加载一次),在构造类的任何实例之前和调用任何静态方法之前.

  2. 实际初始化块实际上由Java编译器复制到该类具有的每个构造函数中.所以每次在实例初始化块中的代码被执行恰好在构造函数中的代码之前.

  • @GlenPierce你去:https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.7 (3认同)

小智 7

很好的答案由aioobe增加几点

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

这给了

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
Run Code Online (Sandbox Code Playgroud)

它表示明显但似乎更清晰.