Java
代码执行顺序:main
方法,类初始化过程,类实例化过程。
main
方法规则
如果当前类作为 Java
程序运行,则 main
是程序的入口方法
如果当前类仅仅作为类实例,则 main
方法和普通 static
方法一样,只有主动调用时才会执行
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class TestMajorMain { public void major () { System.out.println("TestMajorMain, major function." ); } public TestMajorMain () { System.out.println("TestMajorMain, Constructor." ); } public static void main (String[] args) { System.out.println("TestMajorMain, main." ); TestMinorMain minorMain = new TestMinorMain(); minorMain.minor(); } } public class TestMinorMain { public void minor () { System.out.println("TestMinorMain, minor function." ); } public TestMinorMain () { System.out.println("TestMinorMain, Constructor." ); } public static void main (String[] args) throws InterruptedException { System.out.println("TestMinorMain, main." ); Thread thread = new Thread(new Runnable() { @Override public void run () { while (true ){ } } }); thread.start(); Thread.sleep(100 ); thread.join(); System.out.println("TestMinorMain, quit." ); } } TestMajorMain, main. TestMinorMain, Constructor. TestMinorMain, minor function.
Java
代码执行顺序执行顺序理论基础,参考:Java 类加载机制
规则
类初始化过程:静态成员,静态代码块
类实例化过程:即调用构造方法生成实例时
类初始化过程中,可能调用了实例化过程(因为 static
可以修饰方法,属性,代码块,内部类),此时则会暂停类初始化过程而先执行实例化过程(被打断),执行结束后再进行类初始化过程。
示例 下面就是典型的暂停类初始化示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class TestExecSequence { public static int k = 0 ; public static TestExecSequence t1 = new TestExecSequence("t1" ); public static TestExecSequence t2 = new TestExecSequence("t2" ); public static int i = print("i" ); public static int n = 99 ; public int j = print("j" ); { print("constructor code block." ); } static { print("static code block." ); } public TestExecSequence (String str) { System.out.println("###### TestExecSequence Constructor *******" ); System.out.println((++k) + ":" + " i=" + i + " n=" + n + " " + str); ++i; ++n; } public static int print (String str) { System.out.println((++k) + ":" + " i=" + i + " n=" + n + " " + str); ++n; return ++i; } public static void main (String args[]) { System.out.println("****** TestExecSequence main #####" ); TestExecSequence t = new TestExecSequence("main t" ); } } 1 : i=0 n=0 j2 : i=1 n=1 constructor code block.###### TestExecSequence Constructor ******* 3 : i=2 n=2 t14 : i=3 n=3 j5 : i=4 n=4 constructor code block.###### TestExecSequence Constructor ******* 6 : i=5 n=5 t27 : i=6 n=6 i8 : i=7 n=99 static code block.****** TestExecSequence main ##### 9 : i=8 n=100 j10 : i=9 n=101 constructor code block.###### TestExecSequence Constructor ******* 11 : i=10 n=102 main t
所有成员变量在初始化前都是默认初始值。
代码解析:
成员变量默认值:k = i = n = j = 0
代码顺序执行,初始化 k = 0
出现类初始化暂停,t1
执行实例化过程
t1
实例化过程中,先执行成员变量初始化 j
,再执行构造代码块,最后执行构造方法
t1
实例化完后,恢复类初始化过程,接着遇到了 t2
实例化,继续暂停类初始化,执行 t2
实例化过程
同 t1
实例化一样,依次初始化 j
,构造代码块,构造方法
恢复类初始化,静态成员变量初始化 i
和 n = 99
继续类初始化,执行静态代码块
所有静态成员和静态代码块执行完后,进入程序 main
方法
在 main
中,实例化 t
,依次执行初始化 j
,构造代码块,构造方法
子类实例化顺序 规则 子类实例化时会先实例化父类,代码执行顺序基本上参考上面的规则,但是父类先执行,具体如下:
父类类初始化过程:静态成员变量,静态代码块
子类类初始化过程:静态成员变量,静态代码块
父类类实例化过程:普通成员变量,构造代码块,最后父类的构造方法
子类类实例化过程:普通成员变量,构造代码块,最后子类的构造方法
static
静态成员变量和方法是属于类的,所以只会在类初始化时初始化或执行一次,类在多次实例化时不会重复执行。
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 public class Father { public static String staticFatherStr = "StaticFatherStr" ; public String mNormalFatherStr = "NormalFatherStr" ; static { System.out.println("Father static code block, staticFatherStr = " + staticFatherStr); } { System.out.println("Father Constructor code block, mNormalFatherStr = " + mNormalFatherStr); } public Father () { System.out.println("Father Constructor" ); } } public class Son extends Father { public static String staticSonStr = "StaticSonStr" ; public String mNormalSonStr = "NormalSonStr" ; static { System.out.println("Son static code block, staticSonStr = " + staticSonStr); } { System.out.println("Son Constructor code block, mNormalSonStr = " + mNormalSonStr); } public Son () { System.out.println("Son Constructor" ); } public static void main (String[] args) { Son son = new Son(); System.out.println("***** Second Instance.#####" ); Son second = new Son(); } } Father static code block, staticFatherStr = StaticFatherStr Son static code block, staticSonStr = StaticSonStr Father Constructor code block, mNormalFatherStr = NormalFatherStr Father Constructor Son Constructor code block, mNormalSonStr = NormalSonStr Son Constructor ***** Second Instance.##### Father Constructor code block, mNormalFatherStr = NormalFatherStr Father Constructor Son Constructor code block, mNormalSonStr = NormalSonStr Son Constructor
参考文档