Java類的加載和初始化順序分析

不再一一敘述java中的各種定義和規定,

這裏就是舉了兩個例子,詳細闡述,java代碼運行時,成員變量和構造函數的加載和執行順序。


package com.gt.world.oa.aaa;

/**
 * 
 * @author GT
 */
public class Test20140331 {
    public static int k = 0;
    public static Test20140331 t1 = new Test20140331("t1");
    public static Test20140331 t2 = new Test20140331("t2");
    public static int i = print("i");
    public static int n = 99;
     
    public int j = print("j");
     
    {
        print("構造塊");
    }
     
    static {
        print("靜態塊");
    }
 
    public Test20140331(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++i;
        ++n;
    }
 
    private static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);
        ++n;
        return ++i;
    }
 
    public static void main(String[] args) {
    	Test20140331 t = new Test20140331("init");
    	
    	Test20140331 t2 = new Test20140331("init2");
    	
    }
 
}

/**
 *  
 *  1 程序從main函數開始執行 ,執行main函數,需要先加載class文件
 *	2 加載class文件的同時,同時初始化static成員變量和static塊,執行順序爲從上到下依次執行
 *	3 加載class完成之後,初始化成員變量。注:普通代碼塊,可以看作成員變量,執行順序爲從上到下依次執行
 *	4 上面的過程完成之後,再從main函數的第一條語句開始執行。
 *	5 注:靜態成員變量和靜態代碼塊只會 在加載class文件的時候 執行一次
 */

/**
 * public static Test20140331 t1 = new Test20140331("t1");
 * 1>  1:j         i=0    n=0
 * 2>  2:構造塊     i=1    n=1
 * 3>  3:t1        i=2    n=2
 * 
 * public static Test20140331 t2 = new Test20140331("t2");
 * 4>  4:j         i=3    n=3
 * 5>  5:構造塊     i=4    n=4
 * 6>  6:t2        i=5    n=5
 * 
 * public static int i = print("i");
 * 7>  7:i         i=6    n=6
 * 
 * public static int n = 99;
 * 8>  n=99
 * 
 *     static {
	        print("靜態塊");
	    }
 * 9>   8:靜態塊    i=7    n=99
 * 
 * Test20140331 t = new Test20140331("init");
 * 10>  9:j         i=8    n=100
 * 11>  10:構造塊     i=9    n=101
 * 12>  11:init      i=10    n=102
 * 
 *  * Test20140331 t = new Test20140331("init2");
 * 13>  12:j         i=11     n=103
 * 14>  13:構造塊     i=12     n=104
 * 15>  14:init2      i=13    n=105
 * 
 */




package com.gt.world.oa.aaa;

class Insect {
	private int i = 9;
	protected int j;

	public Insect() {
		System.out.println("i = " + i + ",j=" + j);
		j = 39;
	}

	private static int x1 = printInit("static intx1 initialized");

	static int printInit(String s) {
		System.out.println(s);
		return 47;
	}
}

public class Beetle extends Insect {
	private int k = printInit("beetle.k initialized");

	Beetle() {
		System.out.println("k=" + k);
		System.out.println("j = " + j);
	}

	private static int x2 = printInit("static beetle.x2 initialized");

	public static void main(String[] args) {
		System.out.println("beetle constructor");
		Beetle b = new Beetle();
	}
}

/**
 * 1> main方法要執行,需要先加載main方法所在的類的Class文件,
 *    也就是Beetle的Class,因爲Beetle有父類Insect,所以現在加載Insect的Class文件
 * 2>靜態成員變量和靜態代碼塊的初始化和加載Class文件是同步進行的,
 *    所以加載Class文件的同時,完成靜態代碼塊和靜態成員變量的初始化工作
 * 3>Class文件加載完成之後,開始逐條語句執行 main方法
 * 4>在new 對象實例的時候,也會先執行當前類的父類的構造器
 * 5>類的實例化,會按順序初始化 成員變量,最後執行構造函數
 * 
 * 綜上:代碼執行順序如下
 * 1>private static int x1 = printInit("static intx1 initialized");
 * 2>private static int x2 = printInit("static beetle.x2 initialized");
 * 3>System.out.println("beetle constructor");
 * 4>Beetle b = new Beetle();
 * 5>private int i = 9;
 * 6>protected int j;
 * 7>public Insect() {
		System.out.println("i = " + i + ",j=" + j);
		j = 39;
	}
 * 8> private int k = printInit("beetle.k initialized");
 * 9>Beetle() {
		System.out.println("k=" + k);
		System.out.println("j = " + j);
	}
 * 
 */





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章