Verification of Java initialization order (Thinking triggered by Cannot reference XXX before supertype constructor has been called)

1. The discovery of the problem

When I was coding the database recently, I accidentally found an error message, "Cannot reference XXX before supertype constructor has been called". The meaning is obvious, this variable cannot be referenced before the parent class constructor is initialized. When the startic modifier is added to this variable, no more errors will be reported.
Insert picture description here

2. Conjecture verification

So why does it stop reporting errors after adding static modification? Obviously, it is related to the initialization order of Java. Therefore, Coder wrote a verification code to verify the order of Java initialization

/**
 * 父类
 */
public class Base {
    
    

    static String sVar = getString("父类静态变量初始化");
    public String var = getString("父类非静态变量初始化");

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

    {
    
    
        System.out.println("父类的非静态初始化块");
    }

    public Base() {
    
    
        System.out.println("父类构造函数 start");
        draw("父类调用draw方法");//会调用子类覆盖后的方法,这里是null
        System.out.println("父类构造函数 end");
    }

    static String getString(String base) {
    
    
        System.out.println(base);
        return base;
    }

    public void draw(String string) {
    
    
        System.out.println(string);
    }
}
/**
 * 子类
 */
public class SubClass extends Base {
    
    

    public String var = getString("子类初始化非静态变量");
    private String subVar = getString("子类初始化私有变量");
    static String superVar = getString("子类初始化静态变量");

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

    {
    
    
        System.out.println("子类的非静态初始化块");
    }

    SubClass() {
    
    
        System.out.println("子类构造函数start");
        draw("子类调用draw方法");
        System.out.println("子类构造函数end");
    }

    public void draw(String string) {
    
    
        System.out.println(string + subVar);
    }

    public static void main(String[] args) {
    
    
        new SubClass();
    }
}
父类静态变量初始化
父类的静态初始化块
子类初始化静态变量
子类的静态初始化块
父类非静态变量初始化
父类的非静态初始化块
父类构造函数 start
父类调用draw方法 null
父类构造函数 end
子类初始化非静态变量
子类初始化私有变量
子类的非静态初始化块
子类构造函数 start
子类调用draw方法子类初始化私有变量
子类构造函数 end

3. Result analysis

From this result, we can clearly see the reason for the error at the beginning of the article: the initialization of the parent class constructor is earlier than the initialization of the subclass non-static variables, and later than the initialization of the subclass static variables. Therefore, when we change the variable to static modification, no more errors will be reported. You can try the Java initialization process by yourself, which will be of great use in future programming.

Guess you like

Origin blog.csdn.net/bigcharsen/article/details/106387682
Recommended