對象的創建過程
以前只知道當new一個對象時,會自動調用該對象的構造方法來初始化對象,但是對於類成員變量的初始化,以及初始化與構造方法調用的先後關係都不清楚,在閱讀完本章以後對一個對象的整個創建過程有了更清晰的認知。
總結一下對象的創建過程,假設有一個名爲dog的類:
1、雖然沒有關鍵字聲明,但構造方法也算是一個靜態方法,因此當首次new一個dog類的對象時,或調用了dog類的靜態方法,或訪問了靜態成員變量,Java解釋器都會查找類的路徑,以定位Dog.class文件。
2、然後載入Dog.class,有關靜態初始化的所有動作都會執行。因此靜態初始化會在Class對象加載的時候進行一次,並且只進行這一次。
3、當用new Dog()創建對象時,會在堆上爲Dog對象分配足夠的存儲空間,這塊空間會被清零,自動將Dog對象中的基本類型數據設置成默認值,引用設置成null。
4、再執行非靜態成員變量的初始化動作。
5、最後執行構造方法。
綜上類成員變量的初始化發生在構造方法之前,靜態的類成員變量的初始化又在非靜態的類成員變量的初始化之前。
class Window {
Window(int marker) {
System.out.println("Window(" + marker + ")");
}
}
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);
static Window w4 = new Window(4);
}
public class Initialization {
public static void main(String[] args) {
House h = new House();
h.f();
}
}
/*output
Window(4)
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*/
當代碼執行到new House(),會先加載House.class,然後初始化成員變量,在4個成員變量中由於w4是靜態的因此先被初始化,然後按順序初始化w1、w2、w3,成員變量初始化完成後再執行構造方法,w3這個引用又指向了新的對象,所以第一次指向的對象會被丟棄,並作爲垃圾回收。