java的各種載入和初始化的詳細過程

2021-07-25 13:51:17 字數 2081 閱讀 6771

類的載入是通過類載入器(classloader)完成的,它既可以是餓漢式[eagerly load](只要有其它類引用了它就載入)載入類,也可以是懶載入[lazy load](等到類初始化發生的時候才載入)。不過我相信這跟不同的jvm實現有關,然而他又是受jls保證的(當有靜態初始化需求的時候才被載入)

載入完類後,類的初始化就會發生,意味著它會初始化所有類靜態成員,以下情況乙個類被初始化:

例項通過使用new()關鍵字建立或者使用class.forname()反射,但它有可能導致classnotfoundexception。

類的靜態方法被呼叫

類的靜態域被賦值

靜態域被訪問,而且它不是常量

在頂層類中執行assert語句

類載入過程:

1, jvm會先去方法區中找有沒有相應類的.class存在。如果有,就直接使用;如果沒有,則把相關類的.class載入到方法區

2, 在.class載入到方法區時,會分為兩部分載入:先載入非靜態內容,再載入靜態內容

3, 載入非靜態內容:把.class中的所有非靜態內容載入到方法區下的非靜態區域內

4, 載入靜態內容:

4.1、把.class中的所有靜態內容載入到方法區下的靜態區域內

4.2、靜態內容載入完成之後,對所有的靜態變數進行預設初始化

4.3、所有的靜態變數預設初始化完成之後,再進行顯式初始化

4.4、當靜態區域下的所有靜態變數顯式初始化完後,執行靜態**塊

5,當靜態區域下的靜態**塊,執行完之後,整個類的載入就完成了。

6,如果存在繼承關係,則父類先載入,再載入子類。

物件建立過程:

1, 在堆記憶體中開闢一塊空間

2, 給開闢空間分配乙個位址

3, 把物件的所有非靜態成員載入到所開闢的空間下

4, 所有的非靜態成員載入完成之後,對所有非靜態成員變數進行預設初始化

5, 所有非靜態成員變數預設初始化完成之後,呼叫建構函式

6, 在建構函式入棧執行時,分為兩部分:先執行建構函式中的隱式三步,再執行建構函式中書寫的**

6.1、隱式三步: 1

,執行super語句

2,對開闢空間下的所有非靜態成員變數進行顯式初始化 3

,執行構造**塊

6.2、在隱式三步執行完之後,執行建構函式中書寫的**

7,在整個建構函式執行完並彈棧後,把空間分配的位址賦值給乙個引用物件

棧: 用來執行函式。可以儲存區域性資訊

特點:先進後出

堆:用來儲存實體(被new建立出來的)。

特點:1,  每乙個實體所開闢的空間都有乙個位址

2,  每乙個實體中儲存的資料都有乙個預設初始值

方法區:存放class和static。 方法區其實是由n多個小的區域構成。有存放非靜態內容的非靜態區域,還有存放靜態內容的靜態區域,還有存放常量的常量池 等

1、載入過程:

先載入非靜態區域(未例項化),再載入靜態區域預設初始化、顯示初始化,然後執行靜態**塊。父類先載入。(這個過程看不到摸不著,感覺不到,平時也不需要理會這方面的問題,所以不多說)

2、物件建立過程:

對所有非靜態成員變數進行預設初始化,呼叫建構函式,而建構函式分三步走,1、執行super語句,2

、對所有非靜態成員變數進行顯式初始化,3、執行構造**塊。

所以在執行建構函式的**塊之前所有成員變數都已經經過顯示初始化。在整個建構函式執行完並彈棧後,把空間分配的位址賦值給乙個引用物件。

一、無繼承關係

1、初始化靜態成員變數。2、執行靜態**塊。3、初始化

非靜態成員變數。4呼叫建構函式。5、把空間分配的位址賦值給乙個引用物件。

二、存在繼承關係

1、初始化父類靜態成員變數。2、執行父類靜態**塊。3、初始化子類靜態成員變數。

4、執行子類靜態**塊。5、初始化父類非靜態成員變數。

6、執行父類非靜態**塊。7、執行父類建構函式。8、初始化子類非靜態成員變數。

8、執行子類非靜態**塊。9、執行子類建構函式。10、把空間分配的位址賦值給乙個引用物件。

建立乙個有繼承關係的子類物件流程的簡潔總結:先載入父類,再載入子類,例項化父類,最後例項化子類

java 初始化載入

總之一句話,靜態 塊內容先執行,接著執行父類非靜態 塊和構造方法,然後執行子類非靜態 塊和構造方法。注意 子類的構造方法,不管這個構造方法帶不帶引數,預設的它都會先去尋找父類的不帶引數的構造方法。如果父類沒有不帶引數的構造方法,那麼子類必須用supper關鍵子來呼叫父類帶引數的構造方法,否則編譯不能...

java的靜態初始化和動態初始化

package array public class array for int i 0 i 3 i system.out.println for int i 2 i 0 i system.out.println system.out.print b.length n 動態初始化 inta new ...

C 的各種初始化

c 的初始化有很多方式 預設初始化,值初始化,直接初始化,拷貝初始化,列表初始化。這些方式之間有什麼區別與聯絡呢?我們一一來看。1.預設初始化 預設初始化是指定義變數時沒有指定初值時進行的初始化操作。例如int a sales data mydata 等等。這些變數被定義了而不是僅僅被宣告 因為沒有...