Java中一個實例對象被創建的過程
一、類的加載過程
首先,Jvm在執行時,遇到一個新的類時,會到內存中的方法區去找class的信息,如果找到就直接拿來用,如果沒有找到,就會去將類文件加載到方法區。在類加載時,靜態成員變量加載到方法區的靜態區域,非靜態成員變量加載到方法區的非靜態區域。
靜態代碼塊是在類加載時自動執行的代碼,非靜態代碼塊是在創建對象時自動執行的代碼,不創建對象不執行該類的非靜態代碼塊。
加載過程:
1、JVM會先去方法區中找有沒有相應類的.class存在。如果有,就直接使用;如果沒有,則把相關類的.clss加載到方法區。
2、在.class加載到方法區時,先加載父類再加載子類;先加載靜態內容,再加載非靜態內容
3、加載靜態內容:
- 把.class中的所有靜態內容加載到方法區下的靜態區域內
- 靜態內容加載完成之后,對所有的靜態變量進行默認初始化
- 所有的靜態變量默認初始化完成之后,再進行顯式初始化
- 當靜態區域下的所有靜態變量顯式初始化完后,執行靜態代碼塊
4、加載非靜態內容:把.class中的所有非靜態變量及非靜態代碼塊加載到方法區下的非靜態區域內。
5、執行完之后,整個類的加載就完成了。
對於靜態方法和非靜態方法都是被動調用,即系統不會自動調用執行,所以用戶沒有調用時都不執行,主要區別在於靜態方法可以直接用類名直接調用(實例化對象也可以),而非靜態方法只能先實例化對象后才能調用。
二、對象的創建過程
1、new一個對象時,在堆內存中開辟一塊空間。
2、給開辟的空間分配一個地址。
3、把對象的所有非靜態成員加載到所開辟的空間下。
4、所有的非靜態成員加載完成之后,對所有非靜態成員變量進行默認初始化。
5、所有非靜態成員變量默認初始化完成之后,調用構造函數。
6、在構造函數入棧執行時,分為兩部分:先執行構造函數中的隱式三步,
====①執行super()語句 ②對開辟空間下的所有非靜態成員變量進行顯示初始化 ③執行構造代碼塊====
再執行構造函數中書寫的代碼。
7、在整個構造函數執行完並彈棧后,把空間分配的地址賦給引用對象。
注: super語句,可能出現以下三種情況:
1)構造方法體的第一行是this()語句,則不會執行隱式三步,而是調用this()語句所對應的的構造方法,最終肯定會有第一行不是this語句的構造方法。
2)構造方法體的第一行是super()語句,則調用相應的父類的構造方法,
3)構造方法體的第一行既不是this()語句也不是super()語句,則隱式調用super(),即其父類的默認構造方法,這也是為什么一個父類通常要提供默認構造方法的原因。
