Verificación del orden de inicialización de Java (pensamiento desencadenado por No se puede hacer referencia a XXX antes de que se haya llamado al constructor de supertipo)

1. El descubrimiento del problema

Cuando estaba codificando en la base de datos recientemente, encontré accidentalmente un mensaje de error, "No se puede hacer referencia a XXX antes de que se haya llamado al constructor de supertipo". El significado es obvio, no se puede hacer referencia a esta variable antes de que se inicialice el constructor de la clase principal. Cuando se agrega el modificador inicial a esta variable, no se informarán más errores.
Inserte la descripción de la imagen aquí

2. Verificación de conjeturas

Entonces, ¿por qué deja de informar errores después de agregar una modificación estática? Obviamente, está relacionado con el orden de inicialización de Java. Por lo tanto, Coder escribió un código de verificación para verificar el orden de inicialización de Java.

/**
 * 父类
 */
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. Análisis de resultados

A partir de este resultado, podemos ver claramente el motivo del error al comienzo del artículo: la inicialización del constructor de la clase padre es anterior a la inicialización de las variables no estáticas de la subclase y posterior a la inicialización de las variables estáticas de la subclase. Por lo tanto, cuando cambiamos la variable a modificación estática, no se reportarán más errores. Puede probar el proceso de inicialización de Java usted mismo, que será de gran utilidad en la programación futura.

Supongo que te gusta

Origin blog.csdn.net/bigcharsen/article/details/106387682
Recomendado
Clasificación