閱讀原文:Java代碼執行順序java
程序中代碼執行的順序很是重要,稍有不慎便會是程序運行出錯,那麼我將結合實例來分析代碼中的執行。函數
首先了解幾個名詞:this
直接由 { } 包起來的代碼,稱爲非靜態代碼塊
直接由 static { } 包起來的代碼,稱爲靜態代碼塊
好比你定義一個函數void add(int a, int b),這裏的a和b就是形參。
當你進行函數調用的時候,add(1, 2),這裏的1和2就是實參。spa
所謂向前引用,就是在定義類、接口、方法、變量以前使用它們。code
在類體裏面定義的變量稱爲成員變量; 若是該成員變量有 static 關鍵字修飾,則該成員變量稱爲 靜態變量 或 類變量; 若是該成員變量沒有 static 關鍵字修飾,則該成員變量被稱爲 非靜態變量 或 實例變量。
形參、方法內定義的變量、代碼塊中定義的變量,都屬於局部變量。
能夠向前引用 變量屬於類自己 類變量不依賴類的實例,類變量只在初始化時候在方法區中被分配一次空間,不管類的實例被建立幾回,都再也不爲類變量分配空間 經過類的任意一個實例來訪問類變量,底層都將將其轉爲經過類自己來訪問類變量,它們的效果是同樣的 一旦類變量的值被改變,經過類或類的任意一個實例來訪問類變量,獲得的都將是被改變後的值 將在類的初始化以前初始化
不能向前引用,若是向前引用,則稱爲非法向前引用,這是不容許的 變量屬於類的實例對象 隨着類的實例被建立而分配內存空間
public class Parent { public int parentNum=0; public static int staticParentNum=0; { System.out.println("Parent---執行非靜態代碼塊了1!"); } { System.out.println("Parent---執行非靜態代碼塊了2!"); } static{ System.out.println("Parent---執行靜態代碼塊了1!"); } static{ System.out.println("Parent---執行靜態代碼塊了2!"); } public Parent(){ System.out.println("Parent---無參構造函數!"); } public Parent(int parentNum){ this.parentNum=parentNum; System.out.println("Parent---有參構造函數!"); } public void ParentMethod(int parentNum){ this.parentNum=parentNum; System.out.println("Parent---非靜態方法/parentNum="+parentNum); } public static void staticParentMethod(int staticParentNum){ Parent.staticParentNum=staticParentNum; System.out.println("Parent---靜態方法/staticParentNum="+staticParentNum); } }
public class Child extends Parent{ public int childNum=0; public static int staticChildNum=0; { System.out.println("Child---執行非靜態代碼塊了1!"); } { System.out.println("Child---執行非靜態代碼塊了2!"); } static{ System.out.println("Child---執行靜態代碼塊了1!"); } static{ System.out.println("Child---執行靜態代碼塊了2!"); } public Child(){ super(); System.out.println("Child---無參構造函數!"); } public Child(int childNum){ super(childNum); System.out.println("Child---有參構造函數!"); } public void childMethod(int childNum){ this.childNum=childNum; System.out.println("Child--非靜態方法/childNum="+childNum); } public static void staticChildMethod(int staticChildNum){ Child.staticChildNum=staticChildNum; System.out.println("Child---靜態方法/staticChildNum="+staticChildNum); } }
package test; public class Test { // static{ // System.out.println("Test---靜態代碼塊!"); // } public static void main(String[] args) { int key=10; switch (key) { case 0: Parent parent=new Parent(); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---無參構造函數! // 說明:先加載靜態代碼塊,後加載非靜態代碼塊 case 1: Child b= new Child(); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---無參構造函數! // Child---執行非靜態代碼塊了1! // Child---執行非靜態代碼塊了2! // Child---無參構造函數! // 說明:建立子類,會先執行父類,先執行父類靜態——>子類靜態——>父類非靜態——>父類構造 //——>子類非靜態——>子類構造 case 2: Child c= new Child(4); //這個構造函數中指明瞭調用父類的有參構造函數,若不指定,則調用父類無參構造函數 break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---有參構造函數! // Child---執行非靜態代碼塊了1! // Child---執行非靜態代碼塊了2! // Child---有參構造函數! 說明:靜態代碼塊或非靜態代碼塊執行順序,按照代碼先後編寫順序。 case 3: Child d= new Child(); Child e= new Child(4); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---無參構造函數! // Child---執行非靜態代碼塊了1! // Child---執行非靜態代碼塊了2! // Child---無參構造函數! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---有參構造函數! // Child---執行非靜態代碼塊了1! // Child---執行非靜態代碼塊了2! // Child---有參構造函數! 說明:建立多個子類,但父類靜態代碼塊只執行一次。 case 4: Child.staticChildMethod(4); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // Child---靜態方法/staticChildNum=4 說明:靜態方法只能夠調用靜態變量。 case 5: Parent.staticParentMethod(5); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Parent---靜態方法/staticParentNum=5 說明:靜態方法可經過 父類名.靜態方法() 調用。 case 6: System.out.println("父類的靜態變量值staticParentNum="+Parent.staticParentNum); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // 父類的靜態變量值staticParentNum=0 說明:調用靜態變量時,靜態代碼塊會執行。 case 7: System.out.println("子類的靜態變量值staticChildNum="+Child.staticChildNum); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // 子類的靜態變量值staticChildNum=0 說明:調用子類靜態變量,父類靜態代碼塊和子類靜態代碼塊會被執行。 case 8: System.out.println("父類的靜態變量值staticParentNum="+Parent.staticParentNum); System.out.println("子類的靜態變量值staticChildNum="+Child.staticChildNum); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // 父類的靜態變量值staticParentNum=0 // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // 子類的靜態變量值staticChildNum=0 case 9: Child f= new Child(); f.ParentMethod(3); break; // Parent---執行靜態代碼塊了1! // Parent---執行靜態代碼塊了2! // Child---執行靜態代碼塊了1! // Child---執行靜態代碼塊了2! // Parent---執行非靜態代碼塊了1! // Parent---執行非靜態代碼塊了2! // Parent---無參構造函數! // Child---執行非靜態代碼塊了1! // Child---執行非靜態代碼塊了2! // Child---無參構造函數! // Parent---非靜態方法/parentNum=3 說明:建立子類,用子類調用父類方法,非靜態方法能夠調用靜態變量。 default: break; } } }
歡迎關注公衆號交流!
對象