java中靜態塊、類的屬性變數ClassA classA = new ClassA(); 、建構函式的執行順序
阿新 • • 發佈:2019-02-06
1.先看如下程式,判斷執行的 結果:
package com.dbzhang.demo; /** * 驗證類在被初始化的時候的執行順序 * 靜態程式碼塊:static{...} * 類的屬性變數:ClassA classA = new ClassA(); * 構造方法:public classname(){} * @author zdb 2018-06-15 * */ public class ClassOrderTest { static class A{ C c =new C(); public A(){ System.out.println("A's Constructor"); } static { //C c; System.out.println("A's static "); } } static class B extends A{ public B(){ System.out.println("B's Constructor"); } D d = new D(); C c =new C(); static { System.out.println("B's static "); } } static class C { public C(){ System.out.println("C's Constructor"); } static { System.out.println("C's static"); } } static class D{ public D(){ System.out.println("D's Constructor"); } static { System.out.println("D's static"); } } public static void main(String args[]){ System.out.println("start"); B b = new B(); } }
上面的程式碼中,因為幾個類都要在Main方法中執行,因此就宣告為static型別了,這個大家都知道的吧,不宣告為static時,編譯器會報錯: No enclosing instance of type ClassName is accessible. 主要使用了四個靜態內部類。程式碼比較簡答,就不作過多的說明了。
2.執行結果如圖:
start A's static B's static C's static C's Constructor A's Constructor D's static D's Constructor C's Constructor B's Constructor
3.執行的流程圖:
我們看main函式中的語句:
B b = new B();
首先,Java是先初始化類B,初識化的過程中先初始化B的父類,再初始化B本身,因為靜態程式碼塊是在類
初始化的時候載入,而類只初識化一次。
初始化完B的時候:也就是執行B b執行完成。
程式打印出:
start
A's static //父類初始化
B's static //子類初始化
接下來,執行new B();
這個過程程式會先走到B的構造方法,如果B存在父類,則向上到父類的構造方法,也就是A的構造方法,此時會對A的屬性類進行初始化,即
C c=new C();
就會對C進行相應的初始化、例項化的一些過程,如果只是類的屬性類的宣告,如:
C c;
則不對類C進行初始化,更不會例項化。
因此按文章的程式碼,程式會打印出:
C's static //初識化過程
C's Constructor //例項化過程
- 完成之後,就開始執行A的構造方法,程式會打印出:
A's Constructor
父類完成之後,就開始對子類的屬性初始化,以及屬性構造方法呼叫,最後完成子類的例項化。
依此打印出:
D's static //子類屬性類初始化
D's Constructor//子類屬性類例項化
C's Constructor//子類屬性類例項化
B's Constructor//子類例項化
ps:如果將A中的C c=new C();更改為static {C c;}系統也會先執行static程式碼塊,只是,C c只對類C做了宣告,因此這裡也不會對C做初始化工作
注意:(1)靜態塊在類初始化的時候載入了,並且只執行一次;
(2)區別ClassA classA = new ClassA();和ClassA classA;:第一個要初始化和例項化,第二個要只是宣告,也不初始化和例項化。