Java 類中初始化順序問題

一、初始化順序

在類的內部,變量定義的先後順序決定了初始化的順序。即使變量定義散佈於方法定義之間,它們仍會在任何方法(包括構造方法)被調用之前得到初始化。

public class OrderOfInitialization {
    public static void main(String[] args) {
        House h = new House();
        h.f();
    }
}

class House {
    Window w1 = new Window(1);
    House() {
        System.out.println("House()");
        w3 = new Window(33);
    }
    Window w2 = new Window(2);
    void f() {
        System.out.println("f()");
    }
    Window w3 = new Window(3);
}

class Window {
    Window(int marker) {
        System.out.println("Window(" + marker + ")");
    }
}
//output
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()

二、靜態數據的初始化

static關鍵字不能用於局部變量,只能作用於域,如果一個域是靜態的基本類型域,且沒有對其初始化,那麼它就會獲得基本類型的標準初值,如果它是一個對象引用,那麼它的默認初始化就是null。

public class StaticInitialization {
    public static void main(String[] args) {
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

class Bowl {
    Bowl(int marker) {
        System.out.println("Bowl(" + marker + ")");
    }
    void f1(int marker) {
        System.out.println("f1(" + marker + ")");
    }
}

class Table {
    static Bowl bowl1 = new Bowl(1);
    Table() {
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker) {
        System.out.println("f2(" + marker + ")");
    }
    static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard() {
        System.out.println("Cupboard");
        bowl4.f1(2);
    }
    void f3(int marker) {
        System.out.println("f3" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
//output
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard
f1(2)
f2(1)
f3(1)

由輸出可見,靜態初始化只有在必要的時候纔會進行。如果不創建Table對象,也不引用Table.b1,Table.b2,那麼靜態的Bow b1和b2永遠都不會被創建。靜態初始化只在class對象首次加載的時候進行一次,如果某個類沒有被用到,那麼其類的class對象不會被加載,類中的靜態對象,也不會被初始化。

三、非靜態實例的初始化

public class Mugs {
    Mug mug1;
    Mug mug2;
    {
        mug1 = new Mug(1);
        mug2 = new Mug(2);
        System.out.println("mug1 & mug2 initialized");
    }
    Mugs() {
        System.out.println("Mugs()");
    }
    Mugs(int i) {
        System.out.println("Mugs(int)");
    }
    public static void main(String[] args) {
        System.out.println("Inside main()");
        new Mugs();
        System.out.println("new Mugs() completed");
        new Mugs(1);
        System.out.println("new Mugs(1) completed");
    }
}

class Mug {
    Mug(int marker) {
        System.out.println("Mug(" + marker + ")");
    }
    void f(int marker) {
        System.out.println("f(" + marker + ")");
    }
}
//output
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章