我們知道在對象創建之前,一定會先加載類,如果類中包含有靜態元素(屬性和方法),一定會先加載靜態元素,然後再開始創建對象。創建對象無非是調用了構造方法,在創建對象之前,如果定義了塊,一定會先執行程序塊,如果有static修飾的靜態塊,那麼靜態塊會比普通塊先執行。
在有繼承關係的對象創建過程中,問題稍稍變得複雜起來,子類對象在調用構造方法創建子類對象之前,會先調用父類的構造方法。因此父類比子類加載的要早。
java的類加載機制其實是個很複雜的問題,我這裏的對象創建過程有的地方其實還不對,但從理解層面來講,這個順序基本是講的通的。
public class Animal {
public String test = "AnimalField";
public static String testStatic = "AnimalStaticField";
public Animal(){
System.out.println("我是animal中默認無參數的構造方法");
}
{
this.testAnimal();
System.out.println("我是animal中的普通程序塊"+test);
}
static {
testStatic();
System.out.println("我是animal類中靜態程序塊"+testStatic);
}
public void testAnimal(){
System.out.println("我是animal類中的普通方法");
}
public static void testStatic() {
System.out.println("我是animal類中的靜態方法");
}
}
public class Person extends Animal{
public String test = "personField";
public static String testStatic = "personStaticField";
public Person(){
System.out.println("我是person中默認無參數的構造方法");
}
{
this.testPerson();
System.out.println("我是person中的普通程序塊"+test);
}
static {
testStatic();
System.out.println("我是person類中靜態程序塊"+testStatic);
}
public void testPerson(){
System.out.println("我是person類中的普通方法");
}
public static void testStatic() {
System.out.println("我是person類中的靜態方法");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
}
}
輸出結果:
總結來說java類加載的順序以及對象的創建過程爲:(前4步是類加載順序)
- 加載父類的類模板
- 父類會產生自己的靜態空間(靜態屬性,靜態方法,靜態塊,執行靜態塊)
- 加載子類的類模板
- 子類會產生自己的靜態空間(靜態屬性,靜態方法,靜態塊,執行靜態塊)
- 開闢對象空間
- 加載父類的非靜態成員(屬性,方法,塊,構造方法)
- 執行父類的塊,執行父類的構造方法
- 加載子類的非靜態成員(屬性,方法,塊,構造方法)
- 執行子類的塊,執行子類的構造方法
說明:
- 類模板裏存放的只是類的信息,不會執行,然而在產生靜態空間時,靜態塊會執行(程序塊是默認執行的)。
- 實際上在底層加載時先加載的,執行會統一執行。
java學習的小白一個,若寫的有什麼不對的地方,歡迎批評否證。