java静态块非静态块构造函数的初始化顺序

从一个小Demo入手

public class Demo1 {

    static Demo1 demo1 = new Demo1();
    String name1 = "wkw";
    Demo1() {
        System.out.println("我是构造函数");
    }
    {
        System.out.println("我是非静态块" + name1 + name2);
    }
    static String name2 = "yhr";
    static {
        System.out.println("我是静态块" + name2);
    }


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

以下是输出内容
我是非静态块wkwnull
我是构造函数
我是静态块yhr
我是非静态块wkwyhr
我是构造函数

从输出可以看出来,类初始化的时候是先加载静态资源,没有先后顺序,从上到下依次加载,
1.首先加载static Demo1 demo1 = new Demo1();,执行到这一句的时候会去加载非静态块的内容,然后再执行构造函数。这里其实在编译成class文件的时候非静态的内容是在构造函数上面的,两个结合了。
Demo1() { System.out.println("我是非静态块" + this.name1 + name2); System.out.println("我是构造函数"); }
2这里还有
个需要注意点的是静态变量name2的声明放在了非静态块的下面,非静态块引用了name2,然后执行上面的第一个静态变量的时候我当时认为name2还没有声明,是怎么取到值的,后来在class文件里面看到name2定义提升到了方法的前面

    static Demo1 demo1 = new Demo1();
    String name1 = "wkw";
    static String name2 = "yhr";

而且是先声明后赋值,所以才有了第一个输出name2是null的情况,此时name2还没有赋值。
为此我专门做了个实验

public class Demo2 {
    String a = "a";
    String b = b();
    String c = "c";
    public String b() {
        System.out.println(b);
        return a + c;
    }

    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        demo2.b();
        System.out.println(demo2.b);
        System.out.println(demo2.c);
    }
}

结果:
null
anull
anull
c

由于按顺序执行变量的初始化,所以变量b初始化的时候调用了b()方法,此时a初始化完成,c没初始化完成,所以b的值是anull,此时执行到b能调用c变量说明类初始化的时候是先定义变量,再对变量进行赋值的。
相当于:

    String a;
    String b;
    String c;
    {
        a = "a";
        b = b();
        c = "c";
    }

3.接下来再执行静态块的内容,执行完以后就开始执行非静态块,再执行构造函数。
到这里大家应该清楚他们的执行顺序了吧,静态块先执行只执行一次,非静态块后执行,编译的时候把非静态块的内容放到了构造函数的上面,最后再执行构造函数。

猜你喜欢

转载自blog.csdn.net/weixin_44130081/article/details/89390280
今日推荐