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
结论
类加载时,会首先初始化静态属性、执行静态代码块,顺序为代码声明顺序。如果有继承,则先加载父类的,然后加载子类。
如demo中Table、TeaTable、BigTeaTable最先加载完毕。而且BigTeaTable中静态代码块是定义在静态属性之前,所以会按定义顺序加载。静态部分加载完成后,加载非静态部分,最后加载构造。如果有继承则先加载父类的非静态及构造,然后加载子类。如Log所示。
静态属性及代码块只有在首次初始化改类,或者首次调用时才会加载。
如demo中的Cupboard未被初始化和调用,所以静态属性就没有加载。
参考
- 《Thinking in Java》第5章 第5.7节 构造器初始化