zoukankan      html  css  js  c++  java
  • Java 类成员的初始化顺序

    Java 类成员的初始化顺序

    前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究。

     

    1  无继承情况下的Java初始化顺序:

    class Sample {

    Sample(String s) {

    System.out.println(s);

    }

    Sample() {

    System.out.println("Sample默认构造函数被调用");

    }

    }

    class Test {

    static Sample sam=new Sample("静态成员sam初始化");

    Sample sam1=new Sample("sam1成员初始化");

    static {

    System.out.println("static块执行");

    if(sam==null)System.out.println("sam is null");

    sam=new Sample("静态块内初始化sam成员变量");

    }

    Test() {

    System.out.println("Test默认构造函数被调用");

    }

     

    }

     

    //主函数

    public static void main(String str[]) {

     

    Test a=new Test();

     

    }

    输出结果为:

    静态成员sam初始化 -----静态成员初始化

    static块执行 -----静态块被执行

    静态块内初始化sam成员变量 -----静态块执行

    sam1成员初始化 -----普通成员初始化

    Test默认构造函数被调用 -----构造函数执行

    由此可以得出初始化顺序为:

    静态成员变量首先初始化(注意,Static可以看做一个静态成员,其执行顺序和其在类中申明的顺序有关)

    b 普通成员初始化

    c 执行构造函数。

     

    对于静态成员(static块可以看成普通的一个静态成员,其并不一定在类初始化时首先执行)和普通成员,其初始化顺序只与其在类定义中的顺序有关,和其他因素无关。

    例如下面的例子:

    class Test {

    static {

    System.out.println("static 1 执行");

    }

     

    static Sample staticSam1=new Sample("静态成员staticSam1初始化");

     

    Sample sam1=new Sample("sam1成员初始化");

     

    static Sample staticSam2=new Sample("静态成员staticSam2初始化");

     

    static {

    System.out.println("static 2 执行");

    }

     

    Test() {

    System.out.println("Test默认构造函数被调用");

    }

     

    Sample sam2=new Sample("sam2成员初始化");

     

    }

    则结果为:

    static 1 执行

    静态成员staticSam1初始化

    静态成员staticSam2初始化

    static 2 执行

    ------------------------------静态成员

    sam1成员初始化

    sam2成员初始化

    ------------------------------普通成员

    Test默认构造函数被调用

    ------------------------------构造函数

    2 Java继承情况下的初始化顺序:

    class Test {

    static {

    System.out.println("父类static 1 执行");

    }

     

    static Sample staticSam1=new Sample("父类 静态成员staticSam1初始化");

     

    Sample sam1=new Sample("父类 sam1成员初始化");

     

    static Sample staticSam2=new Sample("父类 静态成员staticSam2初始化");

     

    static {

    System.out.println("父类 static 2 执行");

    }

     

    Test() {

    System.out.println("父类 Test默认构造函数被调用");

    }

     

    Sample sam2=new Sample("父类 sam2成员初始化");

     

    }

     

    class TestSub extends Test {

    static Sample staticSamSub=new Sample("子类 静态成员staticSamSub初始化");

     

    TestSub() {

    System.out.println("子类 TestSub 默认构造函数被调用");

    }

     

    Sample sam1=new Sample("子类 sam1成员初始化");

     

    static Sample staticSamSub1=new Sample("子类 静态成员staticSamSub1初始化");

     

    static {System.out.println("子类 static 执行");}

     

    Sample sam2=new Sample("子类 sam2成员初始化");

    }

    执行结果:

    父类 static 1 执行

    父类 静态成员staticSam1初始化

    父类 静态成员staticSam2初始化

    父类 static 2 执行

    --------------------------------父类静态成员初始化

    子类 静态成员staticSamSub初始化

    子类 静态成员staticSamSub1初始化

    子类 static 执行

    --------------------------------子类静态成员初始化

    父类 sam1成员初始化

    父类 sam2成员初始化

    父类 Test默认构造函数被调用

    --------------------------------父类普通成员初始化和构造函数执行

    子类 sam1成员初始化

    子类 sam2成员初始化

    子类 TestSub 默认构造函数被调用

    --------------------------------父类普通成员初始化和构造函数执行

     

     

    由此得出Java初始化顺序为:

    a 继承体系的所有静态成员初始化(先父类,后子类)

    b父类初始化完成(普通成员的初始化-->构造函数的调用)

    c 子类初始化(普通成员-->构造函数)

     

     

    Java初始化顺序如图:

     

    参考文献:

    Java初始化顺序

  • 相关阅读:
    16-镜像命名的最佳实践
    15-RUN vs CMD vs ENTRYPOINT
    14-Dockerfile常用指令
    13-调试Dockerfile
    12-镜像的缓存特性
    11-Dockerfile构建镜像
    10-构建镜像
    09-镜像的分层结构
    08-base镜像
    07-镜像-最小的镜像
  • 原文地址:https://www.cnblogs.com/huangwenjie/p/5808508.html
Copyright © 2011-2022 走看看