class Yao...{
public static void main(String[] args)...{
System.out.println("Yao想參加奧運會");
}
static American american = new American();
}
class American...{
American()...{
System.out.println("American不希望Yao參加奧運會");
}
}
執行結果:
American不希望Yao參加奧運會
Yao想參加奧運會
按照順序執行的規則,結果應該是:
Yao想參加奧運會
American不希望Yao參加奧運會
才對啊?這個怎麼回事??
ps:如果American american = new American();放在main裡邊,就是順序執行了
解釋:
程式在編譯的時候對代碼中所有的類,都會產生對應的.class檔案.
程式在執行的時候會載入所有的.class檔案(包括import匯入的.class檔案和extends繼承來的父類.class檔案)。
然後是進行最佳化,這個就是為什麼有的時候第一次啟動並執行時候會比較慢,以後的時候會很快.
當這一切都完成後,程式進行初始化工作,先初始化static成員(變數,對象or對象的引用),因為要保證所有的變數和引用在使用的時候都要初始化,當然先初始化static成員.
先初始化static成員是java實現這種保證的具體方法。
當然不是所有class中的static變數都在第一次被初始化,對於單獨的class中的static變數或者是對象引用等到比如new 一個的時候才進行初始化
static初始化完成以後才進行構造器的初始化,用預設的或者是你自己覆蓋的構造器.
在這個例子中因為Yao類中有一個static引用變數,所以先初始化static引用.
然而這是new一個American的class,而且這個class裡面沒有static成員,所以就調用構造器American(){}進行對american初始化
當這一切都進行結束後才進行main方法裡面的輸出,所以結果是...
ps:對於代碼static American american = new American();
new American()錯誤:不能在方法體外直接定義堆記憶體,一定要有棧記憶體引用才可以(Syntax error on token "new", delete this token).
American american = new American()不錯但有bug:american的引用是非靜態,所以在沒有建立對象時是無法調用American類的構造方法的.
所以改為:static American american = new American();才可以println出"American不希望Yao參加奧運會".
再給個例子:
class shunxu...{
public static void main(String[] args)...{
int a = 1;
System.out.println("a = " + a + ";b = " + b);//報錯:b cannot be resolved
int b = 2;
}
}
class shunxu2...{
static int a = 1;
public static void main(String[] args)...{
System.out.println("a = " + a + ";b = " + b);
}
static int b = 2;
}