java项目包创建顺序_java程序初始化的顺序
來自:http://blog.csdn.net/socoolfj/article/details/750425 ??http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html
規則1(無繼承情況下):對于靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序依次是
(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器
規則2(有繼承情況下):子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成。靜態變量和靜態初始化塊是依照他們在類中的定義順序進行初始化的。同樣,變量和初始化塊也遵循這個規律。
父類--靜態變量
父類--靜態初始化塊
子類--靜態變量
子類--靜態初始化塊
父類--變量
父類--初始化塊
父類--構造器
子類--變量
子類--初始化塊
子類--構造器
總結:先靜后動,先父后子,從上到下,先變量后構造
原理:
初始化(initialization)其實包含兩部分:
(1)類的初始化(initialization class & interface) (2)對象的創建(creation of new class instances)。
因為類的初始化其實是類加載(loading of classes)的最后一步,所以很多書中把它歸結為“對象的創建”的第一步。其實只是看問題的角度不同而已。為了更清楚的理解,這里還是分開來
1.類的初始化(Initialization classes and interfaces)
(a)初始化類(initialization of class),是指初始化static field 和執行static初始化塊。
例如:class Super {
static String s = “initialization static field”; //初始化static field,其中“= “initialization static field” ”又叫做static field initializer
// static初始化塊,又叫做static initializer,或 static initialization block
static {
System.out.println(“This is static initializer”);
}
}
btw,有些書上提到static initializer 和 static field initializer 的概念,與之對應的還有 instance initializer 和 instance variable initializer。例子中的注釋已經解釋了其含義。
(b)初始化接口(initialization of interface),是指初始化定義在該interface中的field。
*注意*
--initialization classes 時,該class的superclass 將首先被初始化,但其實現的interface則不會。
--initialization classes 時,該class的superclass,以及superlcass的superclass 會首先被遞歸地初始化,一直到java.lang.Object為止。但initialiazation interface的時候,卻不需如此,只會初始化該interface本身。
--對于由引用類變量(class field)所引發的初始化,只會初始化真正定義該field的class
--如果一個static field是編譯時常量(compile-time constant),則對它的引用不會引起定義它的類的初始化。
class Super{
static int x = 2006
}
class Sub extends Super {
static final int y = 2005;
static int z;
static {
System.out.println("Initialization Sub");
}
}
public class Initialization {
public static void main(String[] args) {
System.out.println(Sub.x); // Won't cause initialization of Sub, because x is declared by S, not Sub.
// 不會引起Sub類的初始化,因為x是定義在Super類中的
System.out.println("-------------------------");
System.out.println(Sub.y); // Won't cause initialization of Sub, because y is constant.
// 不會引起Sub類的初始化,因為y是常量
System.out.println("-------------------------");
System.out.println(Sub.z = 2004); // Will cause initialization of Sub class
// 將會引起Sub的初始化
}
}
2.對象的創建(creation of new class instances)
(a) 所有的成員變量—包括該類,及它的父類中的成員變量--被分配內存空間,并賦予默認值。(Btw,這里是第一次初始化成員變量)
(b) 為所調用的構造函數初始化其參數變量。(如果有參數)
(c) 如果在構造函數中用this 調用了同類中的其他構造函數,則按照步驟(b)~(f)去處理被調用到的構造函數。
(d) 如果在構造函數中用super調用了其父類的構造函數,則按照步驟(b)~(f)去處理被調用到的父類構造函數。
(e) 按照書寫順序,執行instance initializer 和 instance variable initializer來初始化成員變量。(Btw,這里是第二次初始化成員變量)
(f) 按照書寫順序,執行constructor的其余部分。
*注意*
成員變量其實都被初始化2次,第一次是賦予默認值,第二次才是你想要設定的值。
最后看一個例子:
class Super{
static {
System.out.println(1);
}
Super(int i){
System.out.println(i);
}
}
class Subclass extends Super implements Interface{
static {
System.out.println(2);
}
Super su = new Super(4);
Subclass() {
super(3);
new Super(5);
}
}
interface Interface{
static Super su = new Super(0);
}
public class InitializationOrder {
public static void main(String[] args) {
Subclass sb = new Subclass();
}
}
稍微解釋一下:
首先,Java虛擬機要執行InitializationOrder類中的static 方法main(),這引起了類的初始化。開始初始化InitializationOrder類。具體的步驟略去不說。
接著,InitializationOrder類初始化完畢后,開始執行main()方法。語句Subclass sb = new Subclass()將創建一個Subclass對象。加載類Subclass后對其進行類初始化,但因為Subclass有一個父類Super,所以先初始化Super類,初始化塊static {System.out.println(1);}被執行,打印輸出1;
第三,Super初始化完畢后,開始初始化Subclass類。static {System.out.println(2);}被執行,打印輸出2;
第四,至此,類的加載工作全部完成。開始進入創建Subclass的對象過程。先為Subclass類和其父類Super類分配內存空間,這時Super su 被附值為null;
第五,執行構造函數Subclass()時,super(3)被執行。如前面(d)所說,Super類的構造函數Super(int i){….}被調用,并按照步驟(b)~(f)來處理。因此,遞歸調用Super類的父類Object類的構造函數,并按照步驟(b)~(f)來初始化Object類,不過沒有任何輸入結果。最后打印輸出3;
第六,如前面(e)所說,初始化成員變量su,其結果是打印輸出4;
第七,如前面(f)所說,執行new Super(5),并打印輸出5;
最后,Subclass雖然實現了接口Interface,但是初始化它的時候并不會引起接口的初始化,所以接口Interface中的static Super su = new Super(0)自始至終都沒有被執行到。
① 類屬性 (靜態變量) 定義時的初始化,如上例的 static String a = "string-a";
② static 塊中的初始化代碼,如上例 static {} 中的 b = "string-b";
③ 對象屬性 (非靜態變量) 定義時的初始化,如上例的 String c = "stirng-c";
④ 構造方法 (函數) 中的初始化代碼,如上例構造方法中的 d = "string-d";
總結
以上是生活随笔為你收集整理的java项目包创建顺序_java程序初始化的顺序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 取出集合前两个数据库_【Jav
- 下一篇: c java 异常_javac -ve