【5 期】面试官:类的初始化顺序

63 阅读1分钟

静态变量和静态代码块优先于实例变量和普通代码块,静态变量和静态代码块的初始化顺序取决于它们在代码中的顺序。

存在继承的情况下,初始化顺序为

  • 父类(静态变量、静态代码块)

  • 子类(静态变量、静态代码块)

  • 父类(实例变量、普通代码块)

  • 父类(构造函数)

  • 子类(实例变量、普通代码块)

  • 子类(构造函数)

public class Parent {
    static {
        System.out.println("Parent static block");      
    }
    
    {
        System.out.println("Parent instance block"); 
    }
    
    public Parent() {   
        System.out.println("Parent constructor"); 
    }
}

public class Child extends Parent {  
    static {     
        System.out.println("Child static block");   
    }
    
    {       
        System.out.println("Child instance block"); 
    }
    
    public Child() {      
        System.out.println("Child constructor");    
    }
    
}

当创建 Child 对象时,先执行父类的静态成员变量和静态初始化块,再执行子类的静态成员变量和静态初始化块,接着执行父类的实例成员变量、实例初始化块和构造方法,最后执行子类的实例成员变量、实例初始化块和构造方法。

final 关键字的特殊处理: 如果成员变量被声明为 final,它必须在对象创建时进行初始化,可以通过直接赋值或者构造方法进行初始化。final 变量的值不能在后续的代码中修改。

public class MyClass {
    final int finalVariable;
    public MyClass() {
        finalVariable = 30;
        System.out.println("Final variable initialized"); 
    }
}

final 变量的初始化通常在构造方法中进行,确保在对象创建时就有一个确定的值。

总体而言,Java 的初始化顺序是相对规范的,但在复杂的继承层次结构和包含多个初始化块的情况下,需要注意一些细节以确保正确的初始化顺序。