天天看點

類的生命周期回顧篇

一、java虛拟機和java程式的生命周期

  java虛拟機的生命周期和java程式的生命周期一緻,當我們在指令行中敲入java指令運作java程式時,java虛拟機程序啟動,程式運作,當程式終止時,則java虛拟機的生命也結束。

  二、類的生命周期

  1、加載:将.class檔案的二進制資料放到記憶體方法區中,并在堆區中建立一個class對象,這個class對象封裝了方法區的資料結構,使用者能通過class對象通路到方法區中。

  2、連接配接

  (1)驗證:驗證.class檔案是否是通過java程式編譯出來的,因為有可能這個.class檔案是黑客特意制造出來的。

  (2)準備:為類中的靜态變量配置設定空間,并初始化為預設值。

  (3)解析:把類的符号引用變為直接引用。

  3.初始化:為靜态變量和靜态塊賦予值。

  java程式對于類的使用方式:

  (1)主動使用。

  (2)被動使用。

  這裡注意:

  java虛拟機對于加載和連接配接的時間節點是很寬松的,沒有嚴格規定,可以提前加載也可以;但是對于初始化,java虛拟機規定當某個類被主動使用時才能初始化。

  我們把3個步驟細講一下:

  1、類的加載:類是通過類加載器進行加載。

  類加載的來源:

  (1)檔案系統中的class檔案

  (2)jar包

  (3)網絡中下載下傳。

  類加載目的地:記憶體。

  類加載器分類:

  (1)根類加載器:沒有父類,加載java.lang.*。

  (2)擴充類加載器:父類是根類加載器,用于加載jrelibext的jar包。

  (3)系統類加載器:父類是擴充類加載器,用于加載classpath的jar包。class scl = class.getsystemclassloader();

 (4)自定義加載器:自定義加載,通常父類是系統類加載器。

  注意:通過類虛拟機自帶的(1)(2)(3)加載器是java虛拟機建立的,而他們加載的類,他的生命周期是虛拟機的生命周期,因為始終被加載器鎖引用。

  2、類的解析

  将符号引用轉換成直接引用。比如:

  a函數調用了b函數,原本隻是符号引用即标明引用了b函數,直接引用是将符号改成指針指向b函數。

  3、類的初始化

  規則:

  (1)初始化的靜态變量都是運作時變量,即不能在編譯時就能判斷值是多少。

  (2)初始化的順序就是按照代碼的順序執行。

  (3)如果初始化子類時父類還沒有被初始化,則先初始化父類。

  初始化時機:當遇到以下情況會進行初始化。

  (1)new建立執行個體、反射建立執行個體、clone建立執行個體、反序列化建立執行個體。

  (2)通路靜态變量,即讀和寫。

  (3)調用靜态方法。

  (4)啟動類需要首先初始化。

  (5)class.forname();

  注意:

  (1)當遇到編譯時常量,則直接用數字替換,而不會導緻類初始化。比如public static final int a= 3;這就是一個編譯時常量。

  (2)當子類對象調用父類的靜态變量或方法,則隻對父類進行初始化。比如:sub.a,其中a是父類的靜态變量,則隻對base初始化。

  (3)當子類被初始化時,父類一定要先初始化;

  但是如果一個類實作了一個接口,當類被初始化時,不用初始化父接口。

  隻有對這個接口進行通路時,才會對接口進行初始化。

  (4)loader.loadclass("....");隻是對類的加載,而不是初始化。

  類加載過程采用“父親委托機制”,即如果loader2的父類是loader1,loader2想要加載test類,則先會檢查loader1是否能夠加載test類,如果能,則通過父類加載。

  運作時包的概念:包名相同,類加載器相同。