有這樣的一段程序:
class Person {
?int age = 0;
?public Person() {
??System.out.println("2、然后執(zhí)行了super");
?}
?public void fun() {
??System.out.println("super.age=" + age);
?}
}
public class Test4 extends Person {
?static {
??System.out.println("1、先執(zhí)行了static區(qū)域");
?}
?int age = 10;
?public Test4() {
??super.fun();
??System.out.println("3、然后執(zhí)行了this() age=" + age);
?}
?public Test4(int age) {
??this();
??System.out.println("4、然后執(zhí)行了this(int age) 年齡是:" + age);
?}
?public static void main(String[] args) {
??Test4 test = new Test4(20);
?}
}
運行的結(jié)果如下:
1、先執(zhí)行了static區(qū)域
2、然后執(zhí)行了super
super.age=0
3、然后執(zhí)行了this() age=10
4、然后執(zhí)行了this(int age) 年齡是:20
????? 有以上程序的運行結(jié)果我們不難發(fā)現(xiàn)java程序的執(zhí)行步驟:對于static域的成員或static變量或static函數(shù)來說在JVM裝載類的時候就已經(jīng)為這些變量分配了實際的空間。在完成這些工作后,程序再去尋找函數(shù)main()的入口,執(zhí)行main()中的代碼塊。
???????在這里順便說一下棧空間和堆空間的區(qū)別:個人認為程序運行時它會申請一片空間,那么在程序中定義的變量在程序運行時都會占用這片空間中的一塊,而堆空間是通過new關(guān)鍵字所產(chǎn)生的對象等所占用的空間。在該程序中,當(dāng)使用new Test4(20)時程序便會首先執(zhí)行該類中非靜態(tài)變量的默認初始化,即在該程序中設(shè)a的初值為0;完成后然后看看構(gòu)造函數(shù)中有沒有傳遞形參過來,若有則先完成對其的賦值,即綁定構(gòu)造方法的參數(shù);然后檢查構(gòu)造函數(shù)中有沒有this()或super()等形式的代碼,若有則優(yōu)先執(zhí)行,于是在該程序中執(zhí)行代碼this();再跳轉(zhuǎn)到另一個構(gòu)造函數(shù),這個構(gòu)造函數(shù)執(zhí)行與第一個構(gòu)造函數(shù)一樣的過程,于是先自動調(diào)用父類的構(gòu)造函數(shù)執(zhí)行其中的代碼,然后再去對在類中定義的變量完成顯示的初始化。一切工作完成后便會接著執(zhí)行構(gòu)造后數(shù)中那些真正屬于它的代碼段。