順序以下java
①父類靜態變量和靜態代碼塊(按照聲明順序);shell
②子類靜態變量和靜態代碼塊(按照聲明順序);數組
③父類成員變量和代碼塊(按照聲明順序);code
④父類構造器;對象
⑤子類成員變量和代碼塊(按照聲明順序);源碼
⑥子類構造器。虛擬機
如下源碼來自牛客中的一道題it
class A { public A() { System.out.println("class A"); } { System.out.println("I'm A class"); } static { System.out.println("class A static"); } } public class B extends A { public B() { System.out.println("class B"); } { System.out.println("I'm B class"); } static { System.out.println("class B static"); } public static void main(String[] args) { new B(); } }
運行結果io
class A static class B static I'm A class class A I'm B class class B
在分析上,若是父類即將調用的方法被子類重寫了,那麼父類就會調用子類重寫後的方法,而不會調用父類的方法。編譯
所以牢記,子類重寫父類方法後,調用時會調用子類重寫後的方法。
如下源碼來自牛客中的一道題
public class Base { private String baseName = "base"; public Base() { callName(); } public void callName() { System.out.println(baseName); } static class Sub extends Base { private String baseName = "sub"; public void callName() { System.out.println(baseName); } } public static void main(String[] args) { Base b = new Sub(); } }
運行結果
null
子類實現的方法中調用的baseName爲子類中的私有屬性。
如下源碼來自牛客中的一道題
public class Demo { class Super { int flag = 1; Super() { test(); } void test() { System.out.println("Super.test() flag=" + flag); } } class Sub extends Super { Sub(int i) { flag = i; System.out.println("Sub.Sub()flag=" + flag); } void test() { System.out.println("Sub.test()flag=" + flag); } } public static void main(String[] args) { new Demo().new Sub(5); } }
運行結果
Sub.test()flag=1 Sub.Sub()flag=5
JVM規範嚴格規定了有且只有5種狀況必須對類進行「初始化」
java.lang.reflect
對類進行反射調用的時候,若類未初始化,則須要先觸發其初始化被動引用:除了以上五種以外,其餘的全部引用類的方式都不會觸發初始化。
如下爲被動引用的狀況
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { System.out.println(SubClass.baseStaticIntVar); } } class Base { static final int baseStaticIntVar = 1; static { System.out.println("Base類的靜態初始化塊..."); } } class SubClass extends Base { static { System.out.println("SubClass類的靜態初始化塊..."); } }
運行結果
1
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { Base[] bases = new Base[5]; SubClass[] subClasses = new SubClass[5]; } } class Base { static { System.out.println("Base類的靜態初始化塊..."); } } class SubClass extends Base { static { System.out.println("SubClass類的靜態初始化塊..."); } }
無運行結果
不會觸發類的初始化,天然不可能調用static代碼塊。
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { System.out.println(A.constantIntVar); } } class A { static { System.out.println("靜態初始化塊..."); } static final int constantIntVar = 100; }
運行結果
100