類的載入是通過類載入器(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 等等。這些變數被定義了而不是僅僅被宣告 因為沒有...