1. 程式人生 > >Java中不同情況下的執行順序整理:

Java中不同情況下的執行順序整理:

      初始化順序:父靜態變數、父靜態程式碼塊、子類靜態變數、子類靜態程式碼塊、父類非靜態變數、父類非靜態程式碼塊、父類構造器、子類非靜態變數、子類非靜態程式碼塊、子類建構函式。

      執行順序:父類B靜態程式碼塊->子類A靜態程式碼塊->父類B非靜態程式碼塊->父類B建構函式->子類A非靜態程式碼塊->子類A建構函式

   例如:

class A {
    public A() {
        System.out.println("A的構造方法");
    }

    public static int j = print();

    public static int print() {
        System.out.println("A print");
        return 521;
    }
}

public class Test1 extends A {
    public Test1() {
        System.out.println("Test1的構造方法");
    }

    public static int k = print();

    public static int print() {
        System.out.println("Test print");
        return 522;
    }

    public static void main(String[] args) {
        System.out.println("main start");
        Test1 t1 = new Test1();
    }
}

  輸出結果為:

A print
Test print
main start
A的構造方法
Test1的構造方法

        2. 類載入過程中,可能呼叫了例項化過程(因為static可以修飾方法,屬性,程式碼塊,內部類),此時則會暫停類載入過程而先執行例項化過程(被打斷),執行結束再進行類載入過程,如下所示:【較難】

public class Text {
    public static int k = 0;
    public static Text t1 = new Text("t1");
    public static Text t2 = new Text("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");

    {
        print("構造塊");
    }
    static {
        print("靜態塊");
    }

    public Text(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++i;
        ++n;
    }

    public static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++n;
        return ++i;
    }

    public static void main(String args[]) {
        Text t = new Text("init");
    }
}

     執行結果 :

1:j   i=0    n=0
2:構造塊   i=1    n=1
3:t1   i=2    n=2
4:j   i=3    n=3
5:構造塊   i=4    n=4
6:t2   i=5    n=5
7:i   i=6    n=6
8:靜態塊   i=7    n=99
9:j   i=8    n=100
10:構造塊   i=9    n=101
11:init   i=10    n=102

          過程解讀:首先會對靜態變數進行初始化,對t1進行初始化時呼叫非靜態方法,所以會被打斷,先執行非靜態變數的初始化,print(j),然後執行非靜態程式碼塊,最後才會執行對t1的初始化,同樣,對於t2的初始化採取一樣的操作,故而前六行的輸出結果如上所示,然後對i進行初始化,呼叫靜態方法,然後執行靜態程式碼塊的初始化,最後對非靜態變數、非靜態程式碼塊進行初始化,最後執行main方法中的程式碼。

public class Son{
    Father father = new Father();
    static{
        System.out.println("Son static");
    }
    public Son(){
        System.out.println("Son()");
    }
}

public class Father {
    static{
        System.out.println("Father static");
    }
    public Father(){
        System.out.println("Father()");
    }
}

public class Main{
    public static void main(String[] args){
        Son son = new Son();
    }
}

  結果為:

Son static
Father static
Father()
Son()

         過程解讀:先執行static程式碼塊,再初始化成員變數,再執行構造方法。

    4.涉及子類與父類時的執行順序:

public class Son extends Father{
    //Father father = new Father();
    static{
        System.out.println("Son static");
    }
    public Son(){
        System.out.println("Son()");
    }
}

public class Father {
    static{
        System.out.println("Father static");
    }
    public Father(){
        System.out.println("Father()");
    }
}

public class Main{
    public static void main(String[] args){
        Son son = new Son();
    }
}

    執行結果如下:

Father static
Son static
Father()
Son()

      過程解讀:先執行父類的static程式碼塊,再執行子類static,再執行構造方法。

     5.多次建立物件,執行順序:

public class Test_Static_Class {
    //靜態程式碼塊
	static {
	   
	   System.out.println("靜態程式碼塊");
   }
   {
	   System.out.println("構造塊1");
   }
   //構造方法
   public   Test_Static_Class() {
	   System.out.println("執行了構造方法");
}
   //普通的成員方法
   public void test() {
	   System.out.println("在方法中的普通程式碼塊");
	   //普通的程式碼塊
	   {
		   System.out.println("普通程式碼塊");
	   }
	  
}
   public static void main(String[] args) {
	System.out.println("執行了主方法");
	System.out.println("--------------------");
	new Test_Static_Class();
	System.out.println("------第二次建立物件---------------");
	new Test_Static_Class();
	System.out.println("------第三次建立物件---------------");
	new Test_Static_Class().test();
}
   //構造塊
   {
	   System.out.println("構造塊2");
   }
}

    執行結果:

        過程解讀:多次建立物件,靜態程式碼塊只執行一次,且最先執行。接下來執行的是構造快,構造塊會每建立一個物件執行一次,且多個構造塊會由上到下的執行。