Java靜態方法,靜態變數,初始化順序 阿新 • • 發佈:2018-12-13 靜態方法的宣告和定義 定義一個靜態方法和定義一個例項方法,在形式上並沒有什麼區別,只是在宣告的頭部,需要加上一個關鍵字static。它的一般語法形式如下: [訪問許可權修飾符] static [返回值型別] 方法名([引數列表]){ 語句序列 } 例如下面是一個靜態的方法: public static void stFun(){ System.out.println(“這是一個靜態方法”); } 3.靜態方法和例項方法的區別 靜態方法和例項方法的區別主要體現在兩個方面: ● 在外部呼叫靜態方法時,可以使用“類名.方法名”的方式,也可以使用“物件名.方法名”的方式。而例項方法只有後面這種方式。也就是說,呼叫靜態方法可以無需建立物件。 ● 靜態方法在訪問本類的成員時,只允許訪問靜態成員(即靜態成員變數和靜態方法),而不允許訪問例項成員變數和例項方法;例項方法則無此限制。 例項程式碼: 靜態方法訪問成員變數示例 class accessMember{ private static int sa; //定義一個靜態成員變數 private int ia; //定義一個例項成員變數 //下面定義一個靜態方法 static void statMethod(){ int i = 0; //正確,可以有自己的區域性變數 sa = 10; //正確,靜態方法可以使用靜態變數 otherStat(); //正確,可以呼叫靜態方法 ia = 20; //錯誤,不能使用例項變數 insMethod(); //錯誤,不能呼叫例項方法 } static void otherStat(){ } //下面定義一個例項方法 void insMethod(){ int i = 0; //正確,可以有自己的區域性變數 sa = 15; //正確,可以使用靜態變數 ia = 30; //正確,可以使用例項變數 statMethod(); //正確,可以呼叫靜態方法 } }//end of class accessMember 4.靜態程式碼塊 在類中,可以將某一塊程式碼宣告為靜態的,這樣的程式塊叫靜態初始化段。靜態程式碼塊的一般形式如下: static { 語句序列 } ● 靜態程式碼塊只能定義在類裡面,它獨立於任何方法,不能定義在方法裡面。 ● 靜態程式碼塊裡面的變數都是區域性變數,只在本塊內有效。 ● 靜態程式碼塊會在類被載入時自動執行,而無論載入者是JVM還是其他的類。 ● 一個類中允許定義多個靜態程式碼塊,執行的順序根據定義的順序進行。 ● 靜態程式碼塊只能訪問類的靜態成員,而不允許訪問例項成員。 public class staticBlock{ //定義一個普通的main()方法 public static void main(String args[]){ System.out.println(“This is main method.”); } //定義一個靜態程式碼塊 static{ System.out.println(“This is static block.”); int stVar = 0; //這是一個區域性變數,只在本塊內有效 } } 編譯通過後,用java命令載入本程式,會得到如下輸出: This is static block. This is main method. 從以上輸出結果中可以看出,靜態程式碼塊甚至在main方法之前就被執行。在main()方法中可以完成的任務在靜態程式碼塊中都可以完成。但是二者在執行上仍然有一些區別,main方法是整個程式啟動的入口,而靜態程式碼塊是存在於某個類中的一個過程。 5.靜態成員變數 Java允許以類作為靜態成員變數的型別,那麼靜態成員變數就是一個物件。如果是基本資料型別的靜態成員變數,在類的外部可以不必建立物件就直接使用。但如果靜態成員是物件,問題就要複雜得多。因為物件所屬的類,既可能有靜態成員,也可能有例項成員。而其中的例項成員必須要在物件例項化後才能使用,問題的核心在於:系統是否會為靜態的類變數建立例項 。 //-----------檔名supplyTest.java----------------- public class supplyTest{ //定義一個靜態方法供測試用 public static void statShow(){ System.out.println(“這是靜態方法”); } //定義一個例項方法供測試用 public void instShow(){ System.out.println(“這是例項方法”); } }//end of supplyTest.java //-----------檔名supplyTest.java----------------- 下面這個程式中,定義了一個supplyTest型別的變數,作為靜態成員,沒有顯示地例項化它。 //-----------檔名hasStatMember.java----------------- public class hasStatMember{ static supplyTest stVar; //定義一個靜態成員 public static void main(String args[]){ stVar.statShow(); //呼叫靜態方法 stVar.instShow(); //呼叫例項方法 } } //-----------檔名hasStatMember.java----------------- 這個程式可以編譯通過,但它執行的結果如下: 這是靜態方法 Exception in thread “main” java.lang.NullPointerException at hasStatMember.main(hasStatMember.java:5) 從執行結果中可以看出,靜態方法被正常執行,但例項方法不能執行,原因是未建立物件例項。這說明儘管stVar被宣告成static型別,系統仍然不會自動為它建立物件,所以程式必須改成如下內容才能正常執行: //-----------檔名hasStatMember.java----------------- public class hasStatMember{ static supplyTest stVar = new supplyTest(); //定義一個靜態成員並例項化它 public static void main(String args[]){ stVar.statShow(); //呼叫靜態方法 stVar.instShow(); //呼叫例項方法 } } //-----------檔名hasStatMember.java----------------- 程式的輸出結果是: 這是靜態方法 這是例項方法 從輸出結果中可以看出,stVar的例項化是在定義時完成的,這意味著在hasStatMember類的外部可以像在內部一樣使用它。下面這個程式演示了對stVar的使用形式。 //-----------檔名useStVar.java----------------- public class useStVar{ public static void main(String args[]){ hasStatMember.stVar.statShow(); //呼叫靜態方法 hasStatMember.stVar.instShow(); //呼叫例項方法 } } //-----------檔名useStVar.java----------------- 程式的輸出結果如下: 這是靜態方法 這是例項方法 無論是靜態方法還是例項方法,都是通過“類名.靜態變數名.方法名”的形式來使用的。讀者可能會覺得這種形式有點眼熟。確實如此,前面大量使用的“System.out.println”就是這種形式。其中,System是系統預定義好的一個類,out是它的一個靜態成員,println是out的一個例項方法。 6.Java中的初始化順序 JAVA類首次裝入時,會對靜態成員變數或方法進行一次初始化,但方法不被呼叫是不會執行的,靜態成員變數和靜態初始化塊級別相同,非靜態成員變數和非靜態初始化塊級別相同。 初始化順序:先初始化父類的靜態程式碼—>初始化子類的靜態程式碼–> (建立例項時,如果不建立例項,則後面的不執行)初始化父類的非靜態程式碼(變數定義等)—>初始化父類建構函式—>初始化子類非靜態程式碼(變數定義等)—>初始化子類建構函式 類只有在使用New呼叫建立的時候才會被JAVA類裝載器裝入建立類例項時,首先按照父子繼承關係進行初始化類例項建立時候,首先初始化塊部分先執行,然後是構造方法;然後從本類繼承的子類的初始化塊執行,最後是子類的構造方法類消除時候,首先消除子類部分,再消除父類部分