编程语言
首页 > 编程语言> > Java初始化过程及类的加载、继承与初始化

Java初始化过程及类的加载、继承与初始化

作者:互联网

知道Java 类初始化过程有利于我们对其运行过程的理解。
首先:每个类的编译代码都存在于它自己的独立的文件中,该文件只在需要使用程序代码时才会被加载。通常加载发生在创建类的第一个对象时或者该类的静态资源被访问时。
另外,定义为static 类型的代码只会被初始化一次。

首先说结果:
加载顺序:该类的顶级父类的静态代码块 -> 顶级父类的静态成员变量 -> 父类的静态代码块 -> 父类的静态成员变量 -> ... -> 当前类的静态代码块 -> 当前类的静态成员变量 -> 顶级父类构造代码块初始化 -> ... -> 当前类构造代码块初始化 -> 顶级父类构造器初始化 -> ... -> 当前类构造器初始化 -> 运行业务代码...

一、静态资源被访问时的加载的情况

demo 类及其子类

class TestClassInitSuper {
    private int i;
    protected int j;

    TestClassInitSuper() {
        System.out.println("i : " + i + "; j : " + j);
        System.out.println("TestClassInitSuper 构造器已运行");
    }

    {
        i = 0;
        j = 1;
        System.out.println("TestClassInitSuper构造代码块已运行 ");
    }

    static {
        System.out.println("TestClassInitSuper静态代码块已运行 ");
    }

    private static String SUPER_STATIC_STR = printStr("TestClassInitSuper.SUPER_STATIC_STR 已初始化");

    static String printStr(String str) {
        System.out.println(str);
        return str;
    }


}

public class TestClassInit extends TestClassInitSuper {
    private int k = 2;

    {
        System.out.println("TestClassInit构造代码块已运行 ");
    }

    static {
        System.out.println("TestClassInit静态代码块已运行 ");
    }

    public TestClassInit() {
        System.out.println("TestClassInit.k : " + k);
        System.out.println("TestClassInit 构造器已运行");
    }

    public static String STATIC_STR = printStr("TestClassInit 静态成员变量STATIC_STR已初始化");

    public void test() {
        System.out.println("test() 方法运行");
    }
}

再创建一个类单独用于测试:

public class TestInit {

    public static void main(String[] args) {
        // 只调用静态资源
        System.out.println("--- 只调用静态资源情况下的加载 ---");
        System.out.println(TestClassInit.STATIC_STR);
        System.out.println("--- 调用完成 ---");
    }
}

运行结果:

--- 只调用静态资源情况下的加载 ---
TestClassInitSuper静态代码块已运行 
TestClassInitSuper.SUPER_STATIC_STR 已初始化
TestClassInit静态代码块已运行 
TestClassInit 静态成员变量STATIC_STR已初始化
TestClassInit 静态成员变量STATIC_STR已初始化
--- 调用完成 ---

在这个测试中,如果把该main 方法写在TestClassInit类中,结果就可能不太一样了:

TestClassInitSuper静态代码块已运行 
TestClassInitSuper.SUPER_STATIC_STR 已初始化
TestClassInit静态代码块已运行 
TestClassInit 静态成员变量STATIC_STR已初始化
--- 只调用静态资源情况下的加载 ---
TestClassInit 静态成员变量STATIC_STR已初始化
--- 调用完成 ---

原因很简单,在加载到main方法之前,当前类(TestClassInit)首先被加载,然后再执行main 方法。

二、创建对象时的加载顺序

再创建一个类单独测试,第一次创建对象和第二次创建对象的情况:

public class TestInit2 {

    public static void main(String[] args) {
        TestClassInit testObject = new TestClassInit();
        testObject.test();
        System.out.println("--- 第二次加载TestClassInit ---");
        TestClassInit testObject2 = new TestClassInit();
        testObject2.test();
    }
}

运行结果:

TestClassInitSuper静态代码块已运行 
TestClassInitSuper.SUPER_STATIC_STR 已初始化
TestClassInit静态代码块已运行 
TestClassInit 静态成员变量STATIC_STR已初始化
TestClassInitSuper构造代码块已运行 
i : 0; j : 1
TestClassInitSuper 构造器已运行
TestClassInit构造代码块已运行 
TestClassInit.k : 2
TestClassInit 构造器已运行
test() 方法运行
--- 第二次加载TestClassInit ---
TestClassInitSuper构造代码块已运行 
i : 0; j : 1
TestClassInitSuper 构造器已运行
TestClassInit构造代码块已运行 
TestClassInit.k : 2
TestClassInit 构造器已运行
test() 方法运行

参考书籍:《JAVA 编程思想》

标签:初始化,Java,TestClassInitSuper,TestClassInit,静态,及类,System,println
来源: https://www.cnblogs.com/xfyy-2020/p/12865293.html