一文理解透Java中初始化顺序

一.先贴上代码

public class InitOrderDemo extends Father {
    private PObject p = new PObject("子类 - 实例变量");
    static {
        sp = new PObject("子类静态代码块 - 静态变量");
    }
    static PObject sp = new PObject("子类 - 静态变量");
    InitOrderDemo(){
        System.out.println("子类构造函数开始执行 ...");
    }
    public static void main(String[] args) {
        new InitOrderDemo();
    }
}

class Father{
    private PObject p = new PObject("父类 - 实例变量");
    private static PObject sp = new PObject("父类 - 静态变量");
    Father(){
        System.out.println("父类构造函数开始执行 ...");
    }
    {
        p = new PObject("父类实例代码块 - 实例变量");
    }
    static {
        sp = new PObject("父类静态代码块 - 静态变量");
    }
}

class PObject{
    PObject(String type){
        System.out.println("作为 "+type+" 成员的 PObject 构造函数执行 ...");
    }
}

二.运行例程结果

作为 父类 - 静态变量 成员的 PObject 构造函数执行 ...
作为 父类静态代码块 - 静态变量 成员的 PObject 构造函数执行 ...
作为 子类静态代码块 - 静态变量 成员的 PObject 构造函数执行 ...
作为 子类 - 静态变量 成员的 PObject 构造函数执行 ...
作为 父类 - 实例变量 成员的 PObject 构造函数执行 ...
作为 父类实例代码块 - 实例变量 成员的 PObject 构造函数执行 ...
父类构造函数开始执行 ...
作为 子类 - 实例变量 成员的 PObject 构造函数执行 ...
子类构造函数开始执行 ...

三.总结

一句话概括:先静态,后实例。先父类,后子类。
具体顺序如下:

  • 如果没有继承关系,先初始化静态部分,后初始化实例部分
  • 如果有继承关系:
    • 先父类静态部分,后子类静态部分
    • 先父类实例部分,后父类构造函数
    • 先子类实例部分,后子类构造函数
  • 补充部分:
    • 静态部分按类中顺序执行,且静态代码块可以提前引用后面定义的静态成员变量
    • 实例部分(包括实例变量和实例代码块)执行顺序总是在构造器之前,不会按照类中顺序
posted @ 2019-12-01 21:46  snower1995  阅读(148)  评论(0编辑  收藏  举报