类的初始化顺序

Java类中包含如下几类部分:
1.静态变量——用static修饰的变量
2.静态初始化块——static{}圈起来的初始化块
3.静态方法——用static修饰的方法
4.变量
5.初始化块
6.构造器
7.普通方法

对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序是(静态变量、静态初始化块)>(变量、初始化块)>构造器

public class Test1 {
    public static String var1 = getStaticField();
    public String var2 = getField();

    static {
        System.out.println("Test1 静态初始化块 初始化");
    }

    {
        System.out.println("Test1 初始化块 初始化");
    }

    public Test1() {
        System.out.println("Test1 构造函数 初始化");
    }

    public static String getStaticField() {
        String statiFiled = "Static Field Initial";
        System.out.println("Test1 静态变量 初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "Field Initial";
        System.out.println("Test1 普通变量 初始化");
        return filed;
    }

    public static void main(String[] args) {
        Test1 test1 = new Test1();
    }
}

运行该程序,可以看到执行结果如下:

Test1 静态变量 初始化
Test1 静态初始化块 初始化
Test1 普通变量 初始化
Test1 初始化块 初始化
Test1 构造函数 初始化

那静态变量和静态初始化块孰先孰后呢?这跟代码的书写顺序有关,静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。

那么在继承关系下的情况又是如何呢?我们也用一段代码来测试一下。编写一个Test2类继承Test1:

public class Test2 extends Test1 {
    public static String var1 = getStaticField();
    public String var2 = getField();

    static {
        System.out.println("Test2 静态初始化块 初始化");
    }

    {
        System.out.println("Test2 初始化块 初始化");
    }

    public Test2() {
        System.out.println("Test2 构造函数 初始化");
    }

    public static String getStaticField() {
        String statiFiled = "Static Field Initial";
        System.out.println("Test2 静态变量 初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "Field Initial";
        System.out.println("Test2 普通变量 初始化");
        return filed;
    }

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

执行Test2中的main方法,可以看到控制台输出结果如下:

Test1 静态初始化块 初始化
Test1 静态变量 初始化
Test2 静态变量 初始化
Test2 静态初始化块 初始化
Test1 普通变量 初始化
Test1 初始化块 初始化
Test1 构造函数 初始化
Test2 普通变量 初始化
Test2 初始化块 初始化
Test2 构造函数 初始化

由此可以得出结论:
父类(静态变量、静态初始化块)>子类(静态变量、静态初始化块)>父类(变量、初始化块)>父类构造器>子类(变量、初始化块)>子类构造器

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  •   最近在看回顾Java基础的时候,发现看似很简单的类初始化的顺序却并不是那么简单(往往越是简单的东西反而越容易出...
    BrightLoong阅读 1,502评论 0 2
  • Java类的初始化顺序 (静态变量、静态代码块)> 类里的 main()(如果有的话) > (变量、初始化块) >...
    PaulLuv阅读 201评论 1 0
  • 这票文章主要想来说一下Java类各部分(非静态字段初始化、非静态块、静态字段初始化、静态块、构造函数)的执行顺序。...
    第四单元阅读 427评论 0 2
  • 读完本文将了解到 单例模式的常用双重检查锁写法,以及如何避免JVM指令重排序导致的失效 更加高效、安全的内部静态类...
    程序员修仙阅读 2,146评论 2 1
  • 当new一个类对象时,如果该类还未被JVM所加载,则JVM首先加载该类,加载类流程中会有类的初始化操作,也就是类中...
    luoxn28阅读 1,675评论 0 1