类初始化块的执行顺序

Java中,和类初始化相关的代码块有三种:静态初始化块,普通初始化块,类的构造函数。

下面是一个例子:

class A
{
    static
    {
        System.out.println("static A");
    }

    {
        System.out.println("init A");
    }

    public A()
    {
        System.out.println("construct A");
    }
}

这篇笔记记录类初始化时,这三种代码块的执行顺序,以及它们的作用。

静态初始化块

static {}

静态初始化块只会在类第一次装在时执行,并且也只会执行一次。通常用来初始化全局的数据。

普通初始化块

普通初始化块在每次类实例化时都执行,但是初始化代码块在类的构造函数之前执行。类的构造函数中,一些和构造函数参数无关的代码可以放在初始化块中,这样类代码的可读性更好。

构造函数

构造函数(Java中也叫类的方法)确实就是一个函数,可以接受参数,它的作用就是通过传入的参数,为类的成员变量赋值。如果一个类没有显示的编写任何构造函数,它默认会有一个无参数,且什么都不做的构造函数。

三种初始化代码块的执行顺序

我们在一个类中定义这三种代码块,并实例化两次。

class A
{
    static
    {
        System.out.println("static A");
    }

    {
        System.out.println("init A");
    }

    public A()
    {
        System.out.println("construct A");
    }
}

public class Main
{
    public static void main(String[] args)
    {
        new A();
        new A();
    }
}

执行结果:

static A
init A
construct A
init A
construct A

继承时的情况

最近发现,很多笔试题目都会问涉及到继承时,初始化代码块的执行顺序,这里特此记录一下。下面代码中,B类继承A类,实例化B类两次。

class A
{
    static
    {
        System.out.println("static A");
    }

    {
        System.out.println("init A");
    }

    public A()
    {
        System.out.println("construct A");
    }
}

class B extends A
{
    static
    {
        System.out.println("static B");
    }

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

    public B()
    {
        System.out.println("construct B");
    }
}

public class Main
{
    public static void main(String[] args)
    {
        new B();
        new B();
    }
}

执行结果:

static A //静态初始化代码块最先执行
static B
init A //第一次实例化B
construct A
init B
construct B
init A //第二次实例化B
construct A
init B
construct B

可以看到,无论如何,静态初始化代码块只执行1次,且最先执行,初始化代码块先于构造函数执行。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。