阿里巴巴2014校園招聘研發筆試JAVA附加題一

題目:

public class Test {
    public static int k = 0;

    public static Test t1 = new Test("t1");// 3

    public static Test t2 = new Test("t2");// 6

    public static int i = print("i");// 7

    public static int n = 99;

    private int a = 0;

    public int j = print("j");// 1,4
    {
        print("構造塊");// 2,5
    }
    static {
        print("靜態塊");// 8
    }

    public Test(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[]) {
        Test t = new Test("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
解析:
1. 若沒有main函數中的代碼,結果1-8仍可輸出,因爲這是在程序編譯時就執行的
2. 對於類中的各代碼的執行順序:靜態變量在類編譯時全部初始化,非靜態變量僅在實例化時才初始化所以先初始化t1,newTest1()時會將類中非靜態變量初始化,所以初始化j,非靜態代碼塊,然後調用構造函數,t2亦是如此,最後類編譯完後,進入main函數,執行t,t初始化前先將Test中非靜態變量初始化,然後調用構造函數
3. 對於經繼承關係的類的執行順序:父類靜態代碼塊和變量->子類靜態代碼塊和變量->父類非靜態代碼塊->父類構造函數->->子類非靜態代碼塊->子類構造函數

4.詳細過程:
1.在加載類Test時候,先爲k,t1,t2,i,n,a,j分配內存,她們的默認值分別爲k=0,t1=null,t2=null,i=0,n=0,a=0,j=0
2.執行public static Test t1 = new Test("t1");     爲t1申請一塊內存,併爲他的屬性j賦值,調用print("j"),此時Test類的i,n都還是爲0,故打印的第一行爲:1:j   i=0    n=0   ;調用t1的構造塊,打印第二行: 2:構造塊   i=1    n=1   ;  然後調用Test的構造函數public Test(String str){};打印第三行:3:t1   i=2    n=2   ;
3.執行public static Test t2 = new Test("t2");   爲t2申請一塊內存,併爲他的屬性值j賦值,調用print("j"),此時Test類的i=3  n=3   打印第4行爲:4:j   i=3    n=3   調用t2的構造塊,打印第5行: 5:構造塊   i=4    n=4     ;然後調用Test的構造函數pbulic Test(String str){};打印第6  行:6:t2   i=5    n=5     ;
4.接着執行public static int i = print("i"); 打印第7行:  7:i   i=6    n=6
5.接着執行public static int n = 99;
6.接着是Test的靜態構造塊:打印第8行  8:靜態塊   i=7    n=99

此時已經把Test.class完全加載到內存了
7.再按着建立t1,t2的方式加載 init

注意:
1.類的靜態屬性的賦值過程,是按着從上到下的先後順序進行的!!!

2.每new一個Test對象,就會執行
public int j = print("j");//1,4
{
   print("構造塊");//2,5
}    
static
{        
print("靜態塊");//8
}



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