1. 程式人生 > >java中靜態塊、類的屬性變數ClassA classA = new ClassA(); 、建構函式的執行順序

java中靜態塊、類的屬性變數ClassA classA = new ClassA(); 、建構函式的執行順序

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;:第一個要初始化和例項化,第二個要只是宣告,也不初始化和例項化。