Object A =new Object();
java中new一個物件要經歷哪些程序
首先java在new一個物件的時候,會先查看物件所屬的類有沒有被加載到記憶體,如果沒有的話就會先通過類的全限定名將物件所屬的.class檔案加載到記憶體中,加載并初始化類完成后,再進行物件的創建作業,(全限定名有絕對路徑的意思)
如果是第一次使用該類,new一個物件可以分為兩個程序:加載并初始化類和創建物件
一、類加載程序(第一次使用該類)
java是使用雙親委派模型來進行類的加載的,所以在描述類加載程序前,先看一下它的作業程序:
雙親委托模型的作業程序是:如果一個類加載器(classLoader)收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委托給父類加載器去完成,每一層次的類加載器都是如此,因此所有的加載請求最終都應該傳送到頂層的啟動類加載器中,只有當父類加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需要加載的類)時,子加載器才會嘗試自己去加載,(就是先看上一級有沒有,沒有才自己加載)
使用雙親委托機制的好處是: 采用雙親委派模式的好處是java類隨著它的類加載器一起具備了一種帶有優先級的層次關系,通過這種層級關系可以避免類的重復加載,當父親已經加載了該類時,就沒有必要子classloader再加載一次,其次是考慮到安全因素,java核心api中定義型別不會被隨意替換,假設通過網路傳遞一個名為java.lang.Integer的類,發現該類已被加載,并不會重新加載網路傳遞的過來的java.lang.Integer,而直接回傳已加載過的Integer.class,這樣便可以防止核心API庫被隨意篡改,
1.加載
由類加載器負責根據一個類的全限定名來讀取此類的二進制位元組流到JVM內部,并存盤再運行時記憶體區的方法區,然后將其轉換為一個與目標型別對應的java.lang.class物件實體
2、驗證
格式驗證:驗證是否符合class檔案規范
語意驗證:檢查一個被標記為final的型別是否包含子類,檢查一個類中的final方法是否被子類進行重寫;
確保父類和子類之間沒有不兼容的一些方法宣告(比如方法簽名相同,但是方法的回傳值不同)
操作驗證:在運算元堆疊中的資料必須進行正確的操作,對常量池中的各種符號參考執行驗證(通常在決議階段執行,檢查是否可以通過符號參考中描述的全限定名定位到指定型別上,以及類成員資訊的訪問修飾符是否允許訪問等)
3.準備
為類中的所有靜態變數分配記憶體空間,并為其設定一個初始值(由于還沒有產生物件,實體變數不在此操作范圍內)被final修飾的static變數(常量),會直接賦值;
4.決議
將常量池中的符號參考轉為直接參考(得到類或者欄位、方法在記憶體中的指標或者偏移量,以便直接呼叫該方法),這個可以在初始化之后在執行,
決議需要靜態系結的內容,//所有不會被重寫的方法和域都會被靜態系結
2、3、4三個階段又合稱為鏈接階段,鏈接階段要做的是將加載到JVM中的二進制位元組流的類資料資訊合并到JVM的運行時狀態中,
5.初始化(先父后子)
普通成員欄位(非靜態):

4.1為靜態變數賦值
4.2執行static代碼塊,注意:static代碼塊只有jvm能夠呼叫
如果時多執行緒需要同時初始化一個類,僅僅只能允許其中一個執行緒對其執行初始化操作,其余執行緒必須等待,只有在活動執行緒執行完對類的初始化操作之后,才會通知正在等待的其他執行緒,
因為子類存在對父類的依賴,所以類的加載順序是先加載父類后加載子類,初始化也一樣,不過,父類初始化時,子類靜態變數的值也有有的,是默認值,
最終,方法區會存盤當前類類資訊,包括累的靜態變數,類初始化代碼(定義靜態變數時的賦值陳述句和靜態初始化代碼塊)、實體變數定義、實體初始化代碼(定義實體變數時的賦值陳述句實體代碼塊和構造方法)和實體方法,還有父類的類資訊參考,
二、創建物件
1、在堆區分配物件需要的記憶體
分配的記憶體包括本類和父類的所有實體變數,但不包括任何靜態變數,
2.對所有實體變數賦默認值
將方法區內對實體變數的定義拷貝一份到堆區,然后賦默認值
3.執行實體初始化代碼
初始化順序是先初始化父類在初始化子類,初始化時先執行實體代碼然后是構造方法
4.如果有類似于Child c = new Child()形式的c參考的話,在堆疊區定義Child型別參考變數c,然后將堆區物件的地址賦值給它需要注意的是,每個子類物件持有父類物件的參考,可在內部通過super關鍵字來呼叫父類物件,但在外部不可訪問,
通過實體參考呼叫實體方法的時候,先從方法區中物件的實際型別資訊找,找不到的話再去父型別別資訊中找,
如果繼承的層次比較深,要呼叫的方法位于比較上層的父類,則呼叫的效率是比較低的,因為每次呼叫都要經過很多次差找,這時候大多系統會采用一種稱為虛方法表的方法來優化呼叫的效率,
所謂虛方法表,就是在類加載的時候,為每個類創建一個表,這個表包括該類的物件所有的動態系結的方法及其地址,包括父類的方法,但一個方法只有一條記錄,子類重寫了父類方法后只會保留子類的,當通過物件動態系結方法的時候,只需要差找這個表就可以了,而不需要挨個查找每個父類,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/154292.html
標籤:Java
上一篇:SpringBoot + Vue + ElementUI 實作后臺管理系統模板 -- 后端篇(四): 整合阿里云 短信服務、整合 JWT 單點登錄
下一篇:資料庫大檔案分段上傳下載
