下面的代碼在cmd模式下通過javac命令編譯,java命令運行Hello world可以正常輸出。
public class Test { static{ System.out.println("Hello World!"); System.exit(0); }}
在網上看見了這段沒有main方法也可以執行的代碼的時候,為了弄清楚java中代碼的運行先後順序原因,寫了如下兩段測試代碼。
public class TestStatic {/* 靜態代碼塊 */static {System.out.println("我是靜態代碼快,我被執行了!");System.exit(0);//退出程式}/* 靜態方法 */public static void method() {System.out.println("我是靜態方法,我被調用執行了!");}/* 構造方法 */public TestStatic() {System.out.println("我是構造方法,我被執行了!");}/* 普通的方法 */public void fc() {System.out.println("我是普通的方法,我被調用執行了!");}public static void main(String[] args) {TestStatic d = new TestStatic();TestStatic.method();d.fc();}}
程式的輸出:我是靜態代碼快,我被執行了!
public class TestStatic {/* 靜態代碼塊 */static {System.out.println("我是靜態代碼快,我被執行了!");}/* 靜態方法 */public static void method() {System.out.println("我是靜態方法,我被調用執行了!");}/* 構造方法 */public TestStatic() {System.out.println("我是構造方法,我被執行了!");}/* 普通的方法 */public void fc() {System.out.println("我是普通的方法,我被調用執行了!");}public static void main(String[] args) {TestStatic d = new TestStatic();TestStatic.method();d.fc();}}
程式的輸出:
我是靜態代碼快,我被執行了!我是構造方法,我被執行了!我是靜態方法,我被調用執行了!我是普通的方法,我被調用執行了!
兩段代碼的輸出結果對比著看,第一行都是先輸出了類中靜態代碼快中的內容,第一段程式的靜態代碼塊中有一句System.exit(0)所以輸出"我是靜態代碼快,我被執行了!後程式會退出,第二段代碼沒有這句輸出了main方法中的內容,可以看出靜態代碼塊在main方法執行前執行了,第二段代碼運行完靜態代碼塊後接下來會去尋找main方法開始執行main方法中的內容,調用構造方法執行個體對象,然後對象去調用執行個體方法,由於靜態方法和執行個體方法都是被動的,需要調用才可以執行,所以誰先被調用誰就先運行,唯一不同的是靜態方法在類載入時就存在了,執行個體方法在new的時候才會產生,所以如果在執行個體對象前用類名去調靜態方法,正是因為這樣它還可以在構造方法調用前被調用。
【注】根據測試結果:最先啟動並執行是靜態代碼塊,靜態方法可以運行在執行個體方法前或者後也可以運行在構造方法的前或者後,但是構造方法一定運行在執行個體方法前面。