类加载时,static、非static、构造的加载顺序

demo

/**
 * 构造中打印Log,便于观察加载顺序
 */
public class Cup {

    public Cup(String container) {
        Log.e("AppTest", "Cup " + container);
    }
    
}

/**
 * Table类,可以放置Cup
 * 包含静态属性、静态代码块、动态属性、构造的Table类
 */

    static Cup cup = new Cup("on Table static");
    
    Cup cup1 = new Cup("on Table non-static");
    
    static {
        Log.e("AppTest", "Table static block");
    }

    public Table() {
        Log.e("AppTest", "init Table");
    }

}

/**
 * TeaTable类,继承自Table
 * 且拥有自己的静态属性、静态代码块、动态属性、构造
 */
public class TeaTable extends Table {

    static Cup cup = new Cup("on TeaTable static");
    
    Cup cup1 = new Cup("on TeaTable non-static");
    
    static {
        Log.e("AppTest", "TeaTable static block");
    }
    
    public TeaTable() {
        Log.e("AppTest", "init TeaTable");
    }

}

/**
 * BigTeaTable 类,继承自TeaTable,
 * 同样拥有自己的静态属性、静态代码块、动态属性、构造
 */
public class BigTeaTable extends TeaTable{

    static {
        Log.e("AppTest", "BigTeaTable static block");
    }
    
    static Cup cup = new Cup("on BigTeaTable static");
    
    Cup cup1 = new Cup("on BigTeaTable non-static");
    
    public BigTeaTable() {
        Log.e("AppTest", "init BigTeaTable");
    }

}

/**
 * Cupboard类,也可以装cup
 * 拥有自己的静态属性、静态代码块、动态属性、构造
 */
public class Cupboard {

    static Cup cup = new Cup("in Cupboard static");

    Cup cup1 = new Cup("in Cupboard non-static");

    static {
        Log.e("AppTest", "Cupboard static block");
    }

    public Cupboard() {
        Log.e("AppTest", "init Cupboard");
    }
}

/**
 * 测试Main方法
 */
main() {
    new BigTeaTable();
}

/**
 * Log输出
 */
06-13 12:26:01.963 E/AppTest: Cup on Table static
06-13 12:26:01.963 E/AppTest: Table static block
06-13 12:26:01.963 E/AppTest: Cup on TeaTable static
06-13 12:26:01.963 E/AppTest: TeaTable static block
06-13 12:26:01.963 E/AppTest: BigTeaTable static block
06-13 12:26:01.963 E/AppTest: Cup on BigTeaTable static
06-13 12:26:01.963 E/AppTest: Cup on Table non-static
06-13 12:26:01.963 E/AppTest: init Table
06-13 12:26:01.963 E/AppTest: Cup on TeaTable non-static
06-13 12:26:01.963 E/AppTest: init TeaTable
06-13 12:26:01.964 E/AppTest: Cup on BigTeaTable non-static
06-13 12:26:01.964 E/AppTest: init BigTeaTable

结论

  1. 类加载时,会首先初始化静态属性、执行静态代码块,顺序为代码声明顺序。如果有继承,则先加载父类的,然后加载子类。
    如demo中Table、TeaTable、BigTeaTable最先加载完毕。而且BigTeaTable中静态代码块是定义在静态属性之前,所以会按定义顺序加载。

  2. 静态部分加载完成后,加载非静态部分,最后加载构造。如果有继承则先加载父类的非静态及构造,然后加载子类。如Log所示。

  3. 静态属性及代码块只有在首次初始化改类,或者首次调用时才会加载。
    如demo中的Cupboard未被初始化和调用,所以静态属性就没有加载。

参考

  • 《Thinking in Java》第5章 第5.7节 构造器初始化

你可能感兴趣的:(类加载时,static、非static、构造的加载顺序)