查看原文
其他

类、变量、块、构造器、继承初始化顺序,终极解答。

2017-11-24 javastack Java技术栈

QQ用得起来越少了,现在就加入300+技术微信群,公众号回复"微信群"即可加入。

最近发现微信群里面有些群友在讨论类的初始化顺序,如类的静态变量、成员变量、静态代码块、非静态代码块、构造器,及继承父类时,它们的初始化顺序都是怎样的,下面我通过例子来说明这个情况,以免被人误导。

示例1:测试单类的初始化顺序

  1. public class ClassInitOrderTest {

  2.    public static String staticField = "static field";

  3.    static {

  4.        System.out.println(staticField);

  5.        System.out.println("static block");

  6.    }

  7.    private String field = "member field";

  8.    {

  9.        System.out.println(field);

  10.        System.out.println("non-static block");

  11.    }

  12.    public ClassInitOrderTest() {

  13.        System.out.println("constructor");

  14.    }

  15.    public static void main(String[] args) {

  16.        new ClassInitOrderTest();

  17.    }

  18. }

程序输出:

  1. static field

  2. static block

  3. member field

  4. non-static block

  5. constructor

可以得出以下结论:

静态变量 > 静态初始块 > 成员变量 > 非静态初始块 > 构造器

示例2:测试类继承的初始化顺序

  1. class Parent {

  2.    private static String parentStaticField = "parent static field";

  3.    static {

  4.        System.out.println(parentStaticField);

  5.        System.out.println("parent static block");

  6.    }

  7.    private String parentField = "parent member field";

  8.    {

  9.        System.out.println(parentField);

  10.        System.out.println("parent non-static block");

  11.    }

  12.    public Parent() {

  13.        System.out.println("parent constructor");

  14.    }

  15. }

  16. public class Child extends Parent {

  17.    private static String childStaticField = "child static field";

  18.    static {

  19.        System.out.println(childStaticField);

  20.        System.out.println("child static block");

  21.    }

  22.    private String childField = "child member field";

  23.    {

  24.        System.out.println(childField);

  25.        System.out.println("child non-static block");

  26.    }

  27.    public Child() {

  28.        System.out.println("child constructor");

  29.    }

  30.    public static void main(String[] args) {

  31.        new Child();

  32.    }

  33. }

程序输出:

  1. parent static field

  2. parent static block

  3. child static field

  4. child static block

  5. parent member field

  6. parent non-static block

  7. parent constructor

  8. child member field

  9. child non-static block

  10. child constructor

可以得出以下结论:

父类静态变量 > 父类静态初始块 > 子类静态变量 > 子类静态初始块 > 父类成员变量 > 父类非静态初始块 > 父类构造器 > 子类成员变量 > 子类非静态初始块 > 子类构造器

示例3:测试成员变量、初始块的初始化顺序

从上面两个例子可以看出,父类的静态变量和静态初始块肯定是先于子类加载的。但同一个类中的静态变量与静态初始块之间,成员变量与初始块之间的顺序一定是变量先于初始块吗?继续演示!

  1. public class TestOrder {

  2.    private static A a = new A();

  3.    static {

  4.        System.out.println("static block");

  5.    }

  6.    private static B b = new B();

  7.    public static void main(String[] args) {

  8.        new TestOrder();

  9.    }

  10. }

  11. class A {

  12.    public A() {

  13.        System.out.println("static field A");

  14.    }

  15. }

  16. class B {

  17.    public B() {

  18.        System.out.println("static field B");

  19.    }

  20. }

程序输出:

  1. static field A

  2. static block

  3. static field B

可以得出以下结论:

静态变量A > 静态初始块 > 静态变量B

所以,它们的在类中的顺序就决定了它们的初始化顺序,而不是变量一定会优先于初始块。

推荐阅读



一张图搞清楚Java异常机制

接口限流算法:漏桶算法&令牌桶算法。

JVM运行时区域详解。

阿里高级Java面试题(首发,70道,带详细答案)

2017派卧底去阿里、京东、美团、滴滴带回来的面试题及答案

Spring面试题(70道,史上最全)



  Java技术栈  
微信公众号:「Javastack

分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。
 ▼长按二维码关注我们↓↓↓



100 32734 100 32734 0 0 4490 0 0:00:07 0:00:07 --:--:-- 7332 * Connection #0 to host 37.48.118.90 left intact

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存